[polly] 3f9bf9f - [Polly][Isl] Update isl to isl-0.24-47-g8853f375

via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 4 10:51:00 PDT 2021


Author: patacca
Date: 2021-07-04T19:50:39+02:00
New Revision: 3f9bf9f42a9043e20c6d2a74dd4f47a90a7e2b41

URL: https://github.com/llvm/llvm-project/commit/3f9bf9f42a9043e20c6d2a74dd4f47a90a7e2b41
DIFF: https://github.com/llvm/llvm-project/commit/3f9bf9f42a9043e20c6d2a74dd4f47a90a7e2b41.diff

LOG: [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

Added: 
    polly/lib/External/isl/cpp/typed_cpp.h.bot
    polly/lib/External/isl/cpp/typed_cpp.h.top
    polly/lib/External/isl/include/isl/typed_cpp.h
    polly/lib/External/isl/interface/plain_cpp.cc
    polly/lib/External/isl/interface/plain_cpp.h
    polly/lib/External/isl/interface/set_lang_defaults_arg4.h
    polly/lib/External/isl/interface/template_cpp.cc
    polly/lib/External/isl/interface/template_cpp.h
    polly/lib/External/isl/isl_list_read_templ.c
    polly/lib/External/isl/isl_multi_zero_space_templ.c
    polly/lib/External/isl/isl_pw_range_tuple_id_templ.c
    polly/lib/External/isl/isl_test2.cc
    polly/lib/External/isl/isl_test_cpp_failed.sh
    polly/lib/External/isl/polyhedron_remove_redundant_equalities.c

Modified: 
    polly/lib/External/isl/AUTHORS
    polly/lib/External/isl/ChangeLog
    polly/lib/External/isl/GIT_HEAD_ID
    polly/lib/External/isl/Makefile.am
    polly/lib/External/isl/Makefile.in
    polly/lib/External/isl/aclocal.m4
    polly/lib/External/isl/compile
    polly/lib/External/isl/config.guess
    polly/lib/External/isl/config.sub
    polly/lib/External/isl/configure
    polly/lib/External/isl/configure.ac
    polly/lib/External/isl/cpp/cpp-checked.h.top
    polly/lib/External/isl/cpp/cpp.h.top
    polly/lib/External/isl/depcomp
    polly/lib/External/isl/doc/Makefile.in
    polly/lib/External/isl/doc/mypod2latex
    polly/lib/External/isl/doc/user.pod
    polly/lib/External/isl/include/isl/aff.h
    polly/lib/External/isl/include/isl/cpp-checked-conversion.h
    polly/lib/External/isl/include/isl/cpp-checked.h
    polly/lib/External/isl/include/isl/cpp.h
    polly/lib/External/isl/include/isl/id.h
    polly/lib/External/isl/include/isl/list.h
    polly/lib/External/isl/include/isl/map.h
    polly/lib/External/isl/include/isl/map_type.h
    polly/lib/External/isl/include/isl/multi.h
    polly/lib/External/isl/include/isl/polynomial.h
    polly/lib/External/isl/include/isl/set.h
    polly/lib/External/isl/include/isl/space.h
    polly/lib/External/isl/include/isl/union_map.h
    polly/lib/External/isl/include/isl/union_set.h
    polly/lib/External/isl/include/isl/val.h
    polly/lib/External/isl/install-sh
    polly/lib/External/isl/interface/Makefile.am
    polly/lib/External/isl/interface/Makefile.in
    polly/lib/External/isl/interface/aclocal.m4
    polly/lib/External/isl/interface/compile
    polly/lib/External/isl/interface/config.guess
    polly/lib/External/isl/interface/config.sub
    polly/lib/External/isl/interface/configure
    polly/lib/External/isl/interface/configure.ac
    polly/lib/External/isl/interface/cpp.cc
    polly/lib/External/isl/interface/cpp.h
    polly/lib/External/isl/interface/depcomp
    polly/lib/External/isl/interface/extract_interface.cc
    polly/lib/External/isl/interface/generator.cc
    polly/lib/External/isl/interface/generator.h
    polly/lib/External/isl/interface/install-sh
    polly/lib/External/isl/interface/isl.py
    polly/lib/External/isl/interface/isl_config.h.in
    polly/lib/External/isl/interface/ltmain.sh
    polly/lib/External/isl/interface/missing
    polly/lib/External/isl/interface/python.cc
    polly/lib/External/isl/isl_aff.c
    polly/lib/External/isl/isl_aff_map.c
    polly/lib/External/isl/isl_aff_private.h
    polly/lib/External/isl/isl_ast_build.c
    polly/lib/External/isl/isl_ast_build_private.h
    polly/lib/External/isl/isl_ast_codegen.c
    polly/lib/External/isl/isl_ast_graft.c
    polly/lib/External/isl/isl_box.c
    polly/lib/External/isl/isl_coalesce.c
    polly/lib/External/isl/isl_constraint.c
    polly/lib/External/isl/isl_id.c
    polly/lib/External/isl/isl_list_templ.c
    polly/lib/External/isl/isl_map.c
    polly/lib/External/isl/isl_map_list.c
    polly/lib/External/isl/isl_map_private.h
    polly/lib/External/isl/isl_map_subtract.c
    polly/lib/External/isl/isl_multi_identity_templ.c
    polly/lib/External/isl/isl_multi_templ.c
    polly/lib/External/isl/isl_multi_tuple_id_templ.c
    polly/lib/External/isl/isl_multi_zero_templ.c
    polly/lib/External/isl/isl_point.c
    polly/lib/External/isl/isl_polynomial.c
    polly/lib/External/isl/isl_schedule_constraints.c
    polly/lib/External/isl/isl_set_list.c
    polly/lib/External/isl/isl_space.c
    polly/lib/External/isl/isl_tab_pip.c
    polly/lib/External/isl/isl_test.c
    polly/lib/External/isl/isl_test_cpp.cc
    polly/lib/External/isl/isl_test_python.py
    polly/lib/External/isl/isl_union_map.c
    polly/lib/External/isl/isl_union_templ.c
    polly/lib/External/isl/isl_val.c
    polly/lib/External/isl/isl_vertices.c
    polly/lib/External/isl/ltmain.sh
    polly/lib/External/isl/m4/ax_detect_clang.m4
    polly/lib/External/isl/m4/libtool.m4
    polly/lib/External/isl/m4/ltoptions.m4
    polly/lib/External/isl/m4/ltsugar.m4
    polly/lib/External/isl/m4/ltversion.m4
    polly/lib/External/isl/m4/lt~obsolete.m4
    polly/lib/External/isl/missing
    polly/lib/External/isl/py-compile
    polly/lib/External/isl/test-driver

Removed: 
    polly/lib/External/isl/cpp/cpp-checked.h.pre
    polly/lib/External/isl/cpp/cpp.h.pre


################################################################################
diff  --git a/polly/lib/External/isl/AUTHORS b/polly/lib/External/isl/AUTHORS
index 8c65c60fd32e3..c6aa5cdad94ca 100644
--- a/polly/lib/External/isl/AUTHORS
+++ b/polly/lib/External/isl/AUTHORS
@@ -38,6 +38,7 @@ Albert Cohen
 Ray Donnelly
 Johannes Doerfert
 Andi Drebes
+Ron Estrin
 Clement Foyer
 Armin Groesslinger
 Tobias Grosser
@@ -47,11 +48,13 @@ Andreas Kloeckner
 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/polly/lib/External/isl/ChangeLog b/polly/lib/External/isl/ChangeLog
index dd4a6b72b6557..44acc42630714 100644
--- a/polly/lib/External/isl/ChangeLog
+++ b/polly/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/polly/lib/External/isl/GIT_HEAD_ID b/polly/lib/External/isl/GIT_HEAD_ID
index cdd3042adf372..d82f0b9576713 100644
--- a/polly/lib/External/isl/GIT_HEAD_ID
+++ b/polly/lib/External/isl/GIT_HEAD_ID
@@ -1 +1 @@
-isl-0.23-61-g24e8cd12
+isl-0.24-47-g8853f375

diff  --git a/polly/lib/External/isl/Makefile.am b/polly/lib/External/isl/Makefile.am
index b526126c9fb37..d403e26d50263 100644
--- a/polly/lib/External/isl/Makefile.am
+++ b/polly/lib/External/isl/Makefile.am
@@ -15,16 +15,17 @@ AUTOMAKE_OPTIONS = nostdinc subdir-objects
 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 @@ libisl_la_LDFLAGS = -version-info @versioninfo@ \
 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_LDADD = libisl.la
 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_LDADD = libisl.la
 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 @@ interface/isl.py: interface/extract_interface$(BUILD_EXEEXT) libdep.a \
 			> $@ || (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 @@ include/isl/cpp-checked-conversion.h: \
 		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 @@ if HAVE_CXX11
     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 @@ EXTRA_DIST = \
 	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 @@ EXTRA_DIST = \
 	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 @@ EXTRA_DIST = \
 	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 @@ EXTRA_DIST = \
 	cpp \
 	python \
 	isl_test_cpp-generic.cc \
+	isl_test_cpp_failed.sh \
 	isl_test_python.py \
 	test_inputs
 

diff  --git a/polly/lib/External/isl/Makefile.in b/polly/lib/External/isl/Makefile.in
index 0b72eb321b6da..0abf9f221cca1 100644
--- a/polly/lib/External/isl/Makefile.in
+++ b/polly/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 @@ host_triplet = @host@
 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)
- at HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE at am__append_1 = isl_test_cpp
- at HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE at am__append_2 = isl_test_cpp
+ at HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE at am__append_1 = isl_test2 isl_test_cpp
+ at HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE at am__append_2 = isl_test2 isl_test_cpp isl_test_cpp_failed.sh
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE at am__append_3 = isl_test_cpp-checked isl_test_cpp-checked-conversion
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE at am__append_4 = isl_test_cpp-checked isl_test_cpp-checked-conversion
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@@HAVE_PYTHON_TRUE at am__append_5 = isl_test_python.py
@@ -116,6 +118,7 @@ TESTS = isl_test$(EXEEXT) codegen_test.sh pip_test.sh bound_test.sh \
 @IMATH_FOR_MP_TRUE@@SMALL_INT_OPT_TRUE@	isl_val_sioimath.c
 
 @IMATH_FOR_MP_TRUE@@SMALL_INT_OPT_FALSE at 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 @@ CONFIG_CLEAN_FILES = isl_srcdir.c bound_test.sh codegen_test.sh \
 	pip_test.sh flow_test.sh schedule_test.sh
 CONFIG_CLEAN_VPATH_FILES =
 @HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE at am__EXEEXT_1 =  \
+ at 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 at am__EXEEXT_2 = isl_test_cpp-checked$(EXEEXT) \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	isl_test_cpp-checked-conversion$(EXEEXT)
@@ -337,6 +341,11 @@ isl_polyhedron_minimize_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
 	$(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_DEPENDENCIES = libisl.la
 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 @@ isl_test_cpp_checked_conversion_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(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 at isl_test_imath_DEPENDENCIES = libisl.la
@@ -458,10 +481,12 @@ am__depfiles_remade = ./$(DEPDIR)/basis_reduction_tab.Plo \
 	./$(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 @@ am__depfiles_remade = ./$(DEPDIR)/basis_reduction_tab.Plo \
 	./$(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 @@ SOURCES = $(libdep_a_SOURCES) $(libisl_la_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
 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__noinst_PYTHON_DIST = interface/isl.py
 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 = $(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 @@ am__set_TESTS_bases = \
   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)
+ at HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE at am__EXEEXT_4 =  \
+ at HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@	isl_test2$(EXEEXT) \
+ at HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@	isl_test_cpp$(EXEEXT) \
+ at 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 @@ am__relativize = \
 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 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -994,7 +1031,7 @@ DIST_SUBDIRS = $(MAYBE_INTERFACE) doc
 ACLOCAL_AMFLAGS = -I m4
 AUTOMAKE_OPTIONS = nostdinc subdir-objects
 lib_LTLIBRARIES = libisl.la
- at HAVE_CPP_ISL_H_TRUE@CPP_H = include/isl/cpp.h
+ at 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 at noinst_PYTHON = interface/isl.py
 TEST_EXTENSIONS = .py
 AM_TESTS_ENVIRONMENT = \
@@ -1159,6 +1196,12 @@ libisl_la_LDFLAGS = -version-info @versioninfo@ \
 
 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 at isl_test_imath_LDFLAGS = @MP_LDFLAGS@
@@ -1215,6 +1258,10 @@ isl_polyhedron_detect_equalities_LDADD = libisl.la
 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_LDADD = libisl.la
 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 @@ pkginclude_HEADERS = \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE at CPP_INTERFACES = \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	include/isl/cpp.h \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	include/isl/cpp-checked.h \
- at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	include/isl/cpp-checked-conversion.h
+ at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	include/isl/cpp-checked-conversion.h \
+ at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	include/isl/typed_cpp.h
 
 BUILT_SOURCES = gitversion.h $(CPP_INTERFACES)
 CLEANFILES = \
@@ -1356,6 +1412,7 @@ EXTRA_DIST = \
 	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 @@ EXTRA_DIST = \
 	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 @@ EXTRA_DIST = \
 	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 @@ EXTRA_DIST = \
 	cpp \
 	python \
 	isl_test_cpp-generic.cc \
+	isl_test_cpp_failed.sh \
 	isl_test_python.py \
 	test_inputs
 
@@ -1645,6 +1705,10 @@ isl_polyhedron_minimize$(EXEEXT): $(isl_polyhedron_minimize_OBJECTS) $(isl_polyh
 	@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 @@ isl_test$(EXEEXT): $(isl_test_OBJECTS) $(isl_test_DEPENDENCIES) $(EXTRA_isl_test
 	@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 @@ isl_test_cpp-checked-conversion$(EXEEXT): $(isl_test_cpp_checked_conversion_OBJE
 	@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 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_tab_pip.Plo at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_tarjan.Plo at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_test.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_test2.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_test_cpp-checked-conversion.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_test_cpp-checked.Po at am__quote@ # am--include-marker
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_test_cpp.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_test_cpp-isl_test_cpp.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_test_imath.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_test_int.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_transitive_closure.Plo at am__quote@ # am--include-marker
@@ -1792,6 +1866,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pip.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/polyhedron_detect_equalities.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/polyhedron_minimize.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/polyhedron_remove_redundant_equalities.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/polyhedron_sample.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/polytope_scan.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/print.Plo at am__quote@ # am--include-marker
@@ -1855,6 +1930,34 @@ am--depfiles: $(am__depfiles_remade)
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
 
+isl_test_cpp-isl_test_cpp.o: isl_test_cpp.cc
+ at 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
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/isl_test_cpp-isl_test_cpp.Tpo $(DEPDIR)/isl_test_cpp-isl_test_cpp.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='isl_test_cpp.cc' object='isl_test_cpp-isl_test_cpp.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at 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
+ at 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`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/isl_test_cpp-isl_test_cpp.Tpo $(DEPDIR)/isl_test_cpp-isl_test_cpp.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='isl_test_cpp.cc' object='isl_test_cpp-isl_test_cpp.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at 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
+ at 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
+ at 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
+ at 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@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at 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
+ at 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`
+ at 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
+ at 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@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at 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_SUITE_LOG): $(TEST_LOGS)
 	  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 @@ schedule_test.sh.log: schedule_test.sh
 	--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 @@ isl_test_cpp.log: isl_test_cpp$(EXEEXT)
 	--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 @@ dist-xz: distdir
 	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 @@ distcheck: dist
 	  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: dist
 	    $(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 @@ installdirs-am:
 	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 @@ distclean: distclean-recursive
 	-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 @@ distclean: distclean-recursive
 	-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 @@ maintainer-clean: maintainer-clean-recursive
 	-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 @@ maintainer-clean: maintainer-clean-recursive
 	-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-am: uninstall-libLTLIBRARIES uninstall-local \
 	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 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-local \
 	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 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-local \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@			> $@ || (rm $@ && false)
 
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE at include/isl/cpp.h: interface/extract_interface$(BUILD_EXEEXT) libdep.a \
- at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cpp/cpp.h.top cpp/cpp.h.pre cpp/cpp.h.bot
- at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	$(MKDIR_P) "include/isl/cpp" && \
- at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	(cat $(srcdir)/cpp/cpp.h.top $(srcdir)/all.h \
- at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	    $(srcdir)/cpp/cpp.h.pre && \
+ at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cpp/cpp.h.top cpp/cpp.h.bot
+ at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	$(MKDIR_P) "include/isl" && \
+ at 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 at include/isl/cpp-checked.h: interface/extract_interface$(BUILD_EXEEXT) libdep.a \
- at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cpp/cpp-checked.h.top \
- at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cpp/cpp-checked.h.pre cpp/cpp-checked.h.bot
- at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	(cat $(srcdir)/cpp/cpp-checked.h.top $(srcdir)/all.h \
- at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	    $(srcdir)/cpp/cpp-checked.h.pre && \
+ at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cpp/cpp-checked.h.top cpp/cpp-checked.h.bot
+ at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	$(MKDIR_P) "include/isl" && \
+ at 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 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-local \
 @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
+ at 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 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-local \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cat $(srcdir)/cpp/cpp-checked-conversion.h.bot) \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@			> $@ || (rm $@ && false)
 
+ at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE at include/isl/typed_cpp.h: interface/extract_interface$(BUILD_EXEEXT) \
+ at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		libdep.a cpp/typed_cpp.h.top cpp/typed_cpp.h.bot
+ at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	$(MKDIR_P) "include/isl" && \
+ at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	(cat $(srcdir)/cpp/typed_cpp.h.top && \
+ at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		interface/extract_interface$(BUILD_EXEEXT) \
+ at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@			--language=template-cpp \
+ at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@			$(includes) $(srcdir)/all.h && \
+ at HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cat $(srcdir)/cpp/typed_cpp.h.bot) \
+ at 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/polly/lib/External/isl/aclocal.m4 b/polly/lib/External/isl/aclocal.m4
index 8600931cd9135..8791b1075388d 100644
--- a/polly/lib/External/isl/aclocal.m4
+++ b/polly/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 @@ You have another version of autoconf.  It may work, but is not guaranteed to.
 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 at 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 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
 [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 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # 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_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 # 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 @@ AC_CONFIG_COMMANDS_PRE(
 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 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
 
 # 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 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
   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 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 
 # 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 @@ for _am_header in $config_headers :; do
 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 @@ if test x"${install_sh+set}" != xset; then
 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 @@ AC_SUBST([am__leading_dot])])
 
 # 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 @@ AC_SUBST([am__quote])])
 
 # 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_DEFUN([AM_MISSING_HAS_RUN],
 [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 @@ fi
 
 # 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_SET_OPTIONS],
 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 @@ AC_LANG_POP([C])])
 # 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 @@ AC_DEFUN([AM_PATH_PYTHON],
     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 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
 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 @@ AC_DEFUN([AM_RUN_LOG],
 
 # 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 @@ AC_CONFIG_COMMANDS_PRE(
 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 @@ AC_SUBST([AM_BACKSLASH])dnl
 _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 @@ fi
 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 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # 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/polly/lib/External/isl/compile b/polly/lib/External/isl/compile
index 99e50524b3bad..23fcba011321a 100755
--- a/polly/lib/External/isl/compile
+++ b/polly/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 at cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -53,7 +53,7 @@ func_file_conv ()
 	  MINGW*)
 	    file_conv=mingw
 	    ;;
-	  CYGWIN*)
+	  CYGWIN* | MSYS*)
 	    file_conv=cygwin
 	    ;;
 	  *)
@@ -67,7 +67,7 @@ func_file_conv ()
 	mingw/*)
 	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
 	  ;;
-	cygwin/*)
+	cygwin/* | msys/*)
 	  file=`cygpath -m "$file" || echo "$file"`
 	  ;;
 	wine/*)

diff  --git a/polly/lib/External/isl/config.guess b/polly/lib/External/isl/config.guess
index f50dcdb6de2af..0fc11edb2d12e 100755
--- a/polly/lib/External/isl/config.guess
+++ b/polly/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 @@ timestamp='2018-02-24'
 # Please send patches to <config-patches at gnu.org>.
 
 
-me=`echo "$0" | sed -e 's,.*/,,'`
+me=$(echo "$0" | sed -e 's,.*/,,')
 
 usage="\
 Usage: $0 [OPTION]
@@ -50,7 +50,7 @@ version="\
 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 @@ if test $# != 0; then
   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 @@ trap 'exit 1' 1 2 15
 
 # 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 at 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 @@ Linux|GNU|GNU/*)
 	# 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 @@ Linux|GNU|GNU/*)
 	#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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	# 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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 		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:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 		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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
     *: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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
     *: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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	# 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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	exit ;;
     Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
 	# akee at 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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 		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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	}
 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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 			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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 			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 @@ EOF
 		    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 @@ EOF
 	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 @@ EOF
 	  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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
     *: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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
     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 @@ EOF
     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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
     *: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 @@ EOF
 	# "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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
     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 @@ copies of config.guess and config.sub with the latest versions from:
   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 at gnu.org to
@@ -1449,31 +1654,32 @@ provide the necessary information to handle your system.
 
 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/polly/lib/External/isl/config.sub b/polly/lib/External/isl/config.sub
index 1d8e98bcee23a..c874b7a9df8a9 100755
--- a/polly/lib/External/isl/config.sub
+++ b/polly/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 @@ timestamp='2018-02-22'
 #	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 @@ Report bugs and patches to <config-patches at gnu.org>."
 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 @@ while test $# -gt 0 ; do
     - )	# 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 @@ case $# in
     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.
-		;;
-	-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
-		;;
-	-bluegene*)
-		os=-cnk
-		;;
-	-sim | -cisco | -oki | -wec | -winbond)
-		os=
-		basic_machine=$1
-		;;
-	-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
+# Separate into logical components for further validation
+case $1 in
+	*-*-*-*-*)
+		echo Invalid configuration \`"$1"\': more than four components >&2
+		exit 1
 		;;
-	-lynx*)
-		os=-lynxos
+	*-*-*-*)
+		basic_machine=$field1-$field2
+		basic_os=$field3-$field4
 		;;
-	-ptx*)
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
+	*-*-*)
+		# 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
 		;;
-	-psos*)
-		os=-psos
+	*-*)
+		# 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
 		;;
-	-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
-		;;
-	c54x)
-		basic_machine=tic54x-unknown
-		;;
-	c55x)
-		basic_machine=tic55x-unknown
-		;;
-	c6x)
-		basic_machine=tic6x-unknown
-		;;
-	leon|leon[3-9])
-		basic_machine=sparc-$basic_machine
-		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
-		basic_machine=$basic_machine-unknown
-		os=-none
+	# 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
 		;;
-	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
+	op50n)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-	ms1)
-		basic_machine=mt-unknown
+	op60c)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-
-	strongarm | thumb | xscale)
-		basic_machine=arm-unknown
+	ibm*)
+		cpu=i370
+		vendor=ibm
 		;;
-	xgate)
-		basic_machine=$basic_machine-unknown
-		os=-none
+	orion105)
+		cpu=clipper
+		vendor=highlevel
 		;;
-	xscaleeb)
-		basic_machine=armeb-unknown
+	mac | mpw | mac-mpw)
+		cpu=m68k
+		vendor=apple
 		;;
-
-	xscaleel)
-		basic_machine=armel-unknown
+	pmac | pmac-mpw)
+		cpu=powerpc
+		vendor=apple
 		;;
 
-	# 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
-		;;
-	# 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
+		cpu=m68000
+		vendor=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
+		cpu=we32k
+		vendor=att
 		;;
 	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
+		cpu=powerpc
+		vendor=ibm
+		basic_os=cnk
 		;;
 	decsystem10* | dec10*)
-		basic_machine=pdp10-dec
-		os=-tops10
+		cpu=pdp10
+		vendor=dec
+		basic_os=tops10
 		;;
 	decsystem20* | dec20*)
-		basic_machine=pdp10-dec
-		os=-tops20
+		cpu=pdp10
+		vendor=dec
+		basic_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
+		cpu=m68k
+		vendor=motorola
 		;;
 	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
+		cpu=m68k
+		vendor=bull
+		basic_os=sysv3
 		;;
 	encore | umax | mmax)
-		basic_machine=ns32k-encore
+		cpu=ns32k
+		vendor=encore
 		;;
-	es1800 | OSE68k | ose68k | ose | OSE)
-		basic_machine=m68k-ericsson
-		os=-ose
+	elxsi)
+		cpu=elxsi
+		vendor=elxsi
+		basic_os=${basic_os:-bsd}
 		;;
 	fx2800)
-		basic_machine=i860-alliant
+		cpu=i860
+		vendor=alliant
 		;;
 	genix)
-		basic_machine=ns32k-ns
-		;;
-	gmicro)
-		basic_machine=tron-gmicro
-		os=-sysv
-		;;
-	go32)
-		basic_machine=i386-pc
-		os=-go32
+		cpu=ns32k
+		vendor=ns
 		;;
 	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
+		cpu=hppa1.1
+		vendor=hitachi
+		basic_os=hiuxwe2
 		;;
 	hp3k9[0-9][0-9] | hp9[0-9][0-9])
-		basic_machine=hppa1.0-hp
+		cpu=hppa1.0
+		vendor=hp
 		;;
 	hp9k2[0-9][0-9] | hp9k31[0-9])
-		basic_machine=m68000-hp
+		cpu=m68000
+		vendor=hp
 		;;
 	hp9k3[2-9][0-9])
-		basic_machine=m68k-hp
+		cpu=m68k
+		vendor=hp
 		;;
 	hp9k6[0-9][0-9] | hp6[0-9][0-9])
-		basic_machine=hppa1.0-hp
+		cpu=hppa1.0
+		vendor=hp
 		;;
 	hp9k7[0-79][0-9] | hp7[0-79][0-9])
-		basic_machine=hppa1.1-hp
+		cpu=hppa1.1
+		vendor=hp
 		;;
 	hp9k78[0-9] | hp78[0-9])
 		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-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
-		basic_machine=hppa1.1-hp
+		cpu=hppa1.1
+		vendor=hp
 		;;
 	hp9k8[0-9][13679] | hp8[0-9][13679])
-		basic_machine=hppa1.1-hp
+		cpu=hppa1.1
+		vendor=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
+		cpu=hppa1.0
+		vendor=hp
 		;;
 	i*86v32)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv32
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=sysv32
 		;;
 	i*86v4*)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv4
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=sysv4
 		;;
 	i*86v)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=sysv
 		;;
 	i*86sol2)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-solaris2
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=solaris2
 		;;
-	i386mach)
-		basic_machine=i386-mach
-		os=-mach
-		;;
-	vsta)
-		basic_machine=i386-unknown
-		os=-vsta
+	j90 | j90-cray)
+		cpu=j90
+		vendor=cray
+		basic_os=${basic_os:-unicos}
 		;;
 	iris | iris4d)
-		basic_machine=mips-sgi
-		case $os in
-		    -irix*)
+		cpu=mips
+		vendor=sgi
+		case $basic_os in
+		    irix*)
 			;;
 		    *)
-			os=-irix4
+			basic_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
+		cpu=m68000
+		vendor=convergent
 		;;
-	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
+	*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		cpu=m68k
+		vendor=atari
+		basic_os=mint
 		;;
 	news-3600 | risc-news)
-		basic_machine=mips-sony
-		os=-newsos
-		;;
-	necv70)
-		basic_machine=v70-nec
-		os=-sysv
+		cpu=mips
+		vendor=sony
+		basic_os=newsos
 		;;
 	next | m*-next)
-		basic_machine=m68k-next
-		case $os in
-		    -nextstep* )
+		cpu=m68k
+		vendor=next
+		case $basic_os in
+		    openstep*)
+		        ;;
+		    nextstep*)
 			;;
-		    -ns2*)
-		      os=-nextstep2
+		    ns2*)
+		      basic_os=nextstep2
 			;;
 		    *)
-		      os=-nextstep3
+		      basic_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
+		cpu=np1
+		vendor=gould
 		;;
 	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
+		cpu=hppa1.1
+		vendor=oki
+		basic_os=proelf
 		;;
 	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
+		cpu=hppa1.1
+		vendor=hitachi
+		basic_os=hiuxwe2
 		;;
 	pbd)
-		basic_machine=sparc-tti
+		cpu=sparc
+		vendor=tti
 		;;
 	pbb)
-		basic_machine=m68k-tti
-		;;
-	pc532 | pc532-*)
-		basic_machine=ns32k-pc532
-		;;
-	pc98)
-		basic_machine=i386-pc
-		;;
-	pc98-*)
-		basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	pentium | p5 | k5 | k6 | nexgen | viac3)
-		basic_machine=i586-pc
-		;;
-	pentiumpro | p6 | 6x86 | athlon | athlon_*)
-		basic_machine=i686-pc
+		cpu=m68k
+		vendor=tti
 		;;
-	pentiumii | pentium2 | pentiumiii | pentium3)
-		basic_machine=i686-pc
-		;;
-	pentium4)
-		basic_machine=i786-pc
-		;;
-	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-		basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	pentiumpro-* | p6-* | 6x86-* | athlon-*)
-		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	pentium4-*)
-		basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	pc532)
+		cpu=ns32k
+		vendor=pc532
 		;;
 	pn)
-		basic_machine=pn-gould
-		;;
-	power)	basic_machine=power-ibm
+		cpu=pn
+		vendor=gould
 		;;
-	ppc | ppcbe)	basic_machine=powerpc-unknown
-		;;
-	ppc-* | ppcbe-*)
-		basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	ppcle | powerpclittle)
-		basic_machine=powerpcle-unknown
-		;;
-	ppcle-* | powerpclittle-*)
-		basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	power)
+		cpu=power
+		vendor=ibm
 		;;
-	ppc64)	basic_machine=powerpc64-unknown
+	ps2)
+		cpu=i386
+		vendor=ibm
 		;;
-	ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	rm[46]00)
+		cpu=mips
+		vendor=siemens
 		;;
-	ppc64le | powerpc64little)
-		basic_machine=powerpc64le-unknown
+	rtpc | rtpc-*)
+		cpu=romp
+		vendor=ibm
 		;;
-	ppc64le-* | powerpc64little-*)
-		basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	sde)
+		cpu=mipsisa32
+		vendor=sde
+		basic_os=${basic_os:-elf}
 		;;
-	ps2)
-		basic_machine=i386-ibm
+	simso-wrs)
+		cpu=sparclite
+		vendor=wrs
+		basic_os=vxworks
 		;;
-	pw32)
-		basic_machine=i586-unknown
-		os=-pw32
+	tower | tower-32)
+		cpu=m68k
+		vendor=ncr
 		;;
-	rdos | rdos64)
-		basic_machine=x86_64-pc
-		os=-rdos
+	vpp*|vx|vx-*)
+		cpu=f301
+		vendor=fujitsu
 		;;
-	rdos32)
-		basic_machine=i386-pc
-		os=-rdos
+	w65)
+		cpu=w65
+		vendor=wdc
 		;;
-	rom68k)
-		basic_machine=m68k-rom68k
-		os=-coff
+	w89k-*)
+		cpu=hppa1.1
+		vendor=winbond
+		basic_os=proelf
 		;;
-	rm[46]00)
-		basic_machine=mips-siemens
+	none)
+		cpu=none
+		vendor=none
 		;;
-	rtpc | rtpc-*)
-		basic_machine=romp-ibm
+	leon|leon[3-9])
+		cpu=sparc
+		vendor=$basic_machine
 		;;
-	s390 | s390-*)
-		basic_machine=s390-ibm
+	leon-*|leon[3-9]-*)
+		cpu=sparc
+		vendor=$(echo "$basic_machine" | sed 's/-.*//')
 		;;
-	s390x | s390x-*)
-		basic_machine=s390x-ibm
+
+	*-*)
+		# shellcheck disable=SC2162
+		IFS="-" read cpu vendor <<EOF
+$basic_machine
+EOF
 		;;
-	sa29200)
-		basic_machine=a29k-amd
-		os=-udi
+	# 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)
+		cpu=$basic_machine
+		vendor=pc
 		;;
-	sb1)
-		basic_machine=mipsisa64sb1-unknown
+	# 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)
+		cpu=i386
+		vendor=pc
 		;;
-	sb1el)
-		basic_machine=mipsisa64sb1el-unknown
+	x64 | amd64)
+		cpu=x86_64
+		vendor=pc
 		;;
-	sde)
-		basic_machine=mipsisa32-sde
-		os=-elf
+	# Recognize the basic CPU types without company name.
+	*)
+		cpu=$basic_machine
+		vendor=unknown
 		;;
-	sei)
-		basic_machine=mips-sei
-		os=-seiux
+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}
 		;;
-	sequent)
-		basic_machine=i386-sequent
+	c90-unknown | c90-cray)
+		vendor=cray
+		basic_os=${Basic_os:-unicos}
 		;;
-	sh5el)
-		basic_machine=sh5le-unknown
+	fx80-unknown)
+		vendor=alliant
 		;;
-	simso-wrs)
-		basic_machine=sparclite-wrs
-		os=-vxworks
+	romp-unknown)
+		vendor=ibm
 		;;
-	sps7)
-		basic_machine=m68k-bull
-		os=-sysv2
+	mmix-unknown)
+		vendor=knuth
 		;;
-	spur)
-		basic_machine=spur-unknown
+	microblaze-unknown | microblazeel-unknown)
+		vendor=xilinx
 		;;
-	st2000)
-		basic_machine=m68k-tandem
+	rs6000-unknown)
+		vendor=ibm
 		;;
-	stratus)
-		basic_machine=i860-stratus
-		os=-sysv4
+	vax-unknown)
+		vendor=dec
 		;;
-	strongarm-* | thumb-*)
-		basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	pdp11-unknown)
+		vendor=dec
 		;;
-	sun2)
-		basic_machine=m68000-sun
+	we32k-unknown)
+		vendor=att
 		;;
-	sun2os3)
-		basic_machine=m68000-sun
-		os=-sunos3
+	cydra-unknown)
+		vendor=cydrome
 		;;
-	sun2os4)
-		basic_machine=m68000-sun
-		os=-sunos4
+	i370-ibm*)
+		vendor=ibm
 		;;
-	sun3os3)
-		basic_machine=m68k-sun
-		os=-sunos3
+	orion-unknown)
+		vendor=highlevel
 		;;
-	sun3os4)
-		basic_machine=m68k-sun
-		os=-sunos4
+	xps-unknown | xps100-unknown)
+		cpu=xps100
+		vendor=honeywell
 		;;
-	sun4os3)
-		basic_machine=sparc-sun
-		os=-sunos3
+
+	# Here we normalize CPU types with a missing or matching vendor
+	dpx20-unknown | dpx20-bull)
+		cpu=rs6000
+		vendor=bull
+		basic_os=${basic_os:-bosx}
 		;;
-	sun4os4)
-		basic_machine=sparc-sun
-		os=-sunos4
+
+	# Here we normalize CPU types irrespective of the vendor
+	amd64-*)
+		cpu=x86_64
 		;;
-	sun4sol2)
-		basic_machine=sparc-sun
-		os=-solaris2
+	blackfin-*)
+		cpu=bfin
+		basic_os=linux
 		;;
-	sun3 | sun3-*)
-		basic_machine=m68k-sun
+	c54x-*)
+		cpu=tic54x
 		;;
-	sun4)
-		basic_machine=sparc-sun
+	c55x-*)
+		cpu=tic55x
 		;;
-	sun386 | sun386i | roadrunner)
-		basic_machine=i386-sun
+	c6x-*)
+		cpu=tic6x
 		;;
-	sv1)
-		basic_machine=sv1-cray
-		os=-unicos
+	e500v[12]-*)
+		cpu=powerpc
+		basic_os=${basic_os}"spe"
 		;;
-	symmetry)
-		basic_machine=i386-sequent
-		os=-dynix
+	mips3*-*)
+		cpu=mips64
 		;;
-	t3e)
-		basic_machine=alphaev5-cray
-		os=-unicos
+	ms1-*)
+		cpu=mt
 		;;
-	t90)
-		basic_machine=t90-cray
-		os=-unicos
+	m68knommu-*)
+		cpu=m68k
+		basic_os=linux
 		;;
-	tile*)
-		basic_machine=$basic_machine-unknown
-		os=-linux-gnu
+	m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
+		cpu=s12z
 		;;
-	tx39)
-		basic_machine=mipstx39-unknown
+	openrisc-*)
+		cpu=or32
 		;;
-	tx39el)
-		basic_machine=mipstx39el-unknown
+	parisc-*)
+		cpu=hppa
+		basic_os=linux
 		;;
-	toad1)
-		basic_machine=pdp10-xkl
-		os=-tops20
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		cpu=i586
 		;;
-	tower | tower-32)
-		basic_machine=m68k-ncr
+	pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
+		cpu=i686
 		;;
-	tpf)
-		basic_machine=s390x-ibm
-		os=-tpf
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		cpu=i686
 		;;
-	udi29k)
-		basic_machine=a29k-amd
-		os=-udi
+	pentium4-*)
+		cpu=i786
 		;;
-	ultra3)
-		basic_machine=a29k-nyu
-		os=-sym1
+	pc98-*)
+		cpu=i386
 		;;
-	v810 | necv810)
-		basic_machine=v810-nec
-		os=-none
+	ppc-* | ppcbe-*)
+		cpu=powerpc
 		;;
-	vaxv)
-		basic_machine=vax-dec
-		os=-sysv
+	ppcle-* | powerpclittle-*)
+		cpu=powerpcle
 		;;
-	vms)
-		basic_machine=vax-dec
-		os=-vms
+	ppc64-*)
+		cpu=powerpc64
 		;;
-	vpp*|vx|vx-*)
-		basic_machine=f301-fujitsu
+	ppc64le-* | powerpc64little-*)
+		cpu=powerpc64le
 		;;
-	vxworks960)
-		basic_machine=i960-wrs
-		os=-vxworks
+	sb1-*)
+		cpu=mipsisa64sb1
 		;;
-	vxworks68)
-		basic_machine=m68k-wrs
-		os=-vxworks
+	sb1el-*)
+		cpu=mipsisa64sb1el
 		;;
-	vxworks29k)
-		basic_machine=a29k-wrs
-		os=-vxworks
+	sh5e[lb]-*)
+		cpu=$(echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/')
 		;;
-	w65*)
-		basic_machine=w65-wdc
-		os=-none
+	spur-*)
+		cpu=spur
 		;;
-	w89k-*)
-		basic_machine=hppa1.1-winbond
-		os=-proelf
+	strongarm-* | thumb-*)
+		cpu=arm
 		;;
-	x64)
-		basic_machine=x86_64-pc
+	tx39-*)
+		cpu=mipstx39
 		;;
-	xbox)
-		basic_machine=i686-pc
-		os=-mingw32
+	tx39el-*)
+		cpu=mipstx39el
 		;;
-	xps | xps100)
-		basic_machine=xps100-honeywell
+	x64-*)
+		cpu=x86_64
 		;;
 	xscale-* | xscalee[bl]-*)
-		basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
+		cpu=$(echo "$cpu" | sed 's/^xscale/arm/')
 		;;
-	ymp)
-		basic_machine=ymp-cray
-		os=-unicos
-		;;
-	none)
-		basic_machine=none-none
-		os=-none
+	arm64-*)
+		cpu=aarch64
 		;;
 
-# 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
+	# Recognize the canonical CPU Types that limit and/or modify the
+	# company names they are paired with.
+	cr16-*)
+		basic_os=${basic_os:-elf}
 		;;
-	op50n)
-		basic_machine=hppa1.1-oki
+	crisv32-* | etraxfs*-*)
+		cpu=crisv32
+		vendor=axis
 		;;
-	op60c)
-		basic_machine=hppa1.1-oki
+	cris-* | etrax*-*)
+		cpu=cris
+		vendor=axis
 		;;
-	romp)
-		basic_machine=romp-ibm
+	crx-*)
+		basic_os=${basic_os:-elf}
 		;;
-	mmix)
-		basic_machine=mmix-knuth
-		;;
-	rs6000)
-		basic_machine=rs6000-ibm
-		;;
-	vax)
-		basic_machine=vax-dec
-		;;
-	pdp11)
-		basic_machine=pdp11-dec
-		;;
-	we32k)
-		basic_machine=we32k-att
-		;;
-	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
-		basic_machine=sh-unknown
+	neo-tandem)
+		cpu=neo
+		vendor=tandem
 		;;
-	cydra)
-		basic_machine=cydra-cydrome
+	nse-tandem)
+		cpu=nse
+		vendor=tandem
 		;;
-	orion)
-		basic_machine=orion-highlevel
+	nsr-tandem)
+		cpu=nsr
+		vendor=tandem
 		;;
-	orion105)
-		basic_machine=clipper-highlevel
+	nsv-tandem)
+		cpu=nsv
+		vendor=tandem
 		;;
-	mac | mpw | mac-mpw)
-		basic_machine=m68k-apple
+	nsx-tandem)
+		cpu=nsx
+		vendor=tandem
 		;;
-	pmac | pmac-mpw)
-		basic_machine=powerpc-apple
+	mipsallegrexel-sony)
+		cpu=mipsallegrexel
+		vendor=sony
 		;;
-	*-unknown)
-		# Make sure to match an already-canonicalized machine name.
+	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 @@ esac
 
 # 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 
diff erent 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.
-		;;
-	-qnx*)
-		case $basic_machine in
-		    x86-* | i*86-*)
-			;;
-		    *)
-			os=-nto$os
-			;;
-		esac
+	# Some version numbers need modification
+	chorusos*)
+		os=chorusos
 		;;
-	-nto-qnx*)
+	isc)
+		os=isc2.2
 		;;
-	-nto*)
-		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+	sco6)
+		os=sco5v6
 		;;
-	-sim | -xray | -os68k* | -v88r* \
-	      | -windows* | -osx | -abug | -netware* | -os9* \
-	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+	sco5)
+		os=sco3.2v5
 		;;
-	-mac*)
-		os=`echo "$os" | sed -e 's|mac|macos|'`
+	sco4)
+		os=sco3.2v4
 		;;
-	-linux-dietlibc)
-		os=-linux-dietlibc
+	sco3.2.[4-9]*)
+		os=$(echo $os | sed -e 's/sco3.2./sco3.2v/')
 		;;
-	-linux*)
-		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+	sco*v* | scout)
+		# Don't match below
 		;;
-	-sunos5*)
-		os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
+	sco*)
+		os=sco3.2v2
 		;;
-	-sunos6*)
-		os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
+	psos*)
+		os=psos
 		;;
-	-opened*)
-		os=-openedition
+	qnx*)
+		os=qnx
 		;;
-	-os400*)
-		os=-os400
+	hiux*)
+		os=hiuxwe2
 		;;
-	-wince*)
-		os=-wince
+	lynx*178)
+		os=lynxos178
 		;;
-	-utek*)
-		os=-bsd
+	lynx*5)
+		os=lynxos5
 		;;
-	-dynix*)
-		os=-bsd
+	lynxos*)
+		# don't get caught up in next wildcard
 		;;
-	-acis*)
-		os=-aos
+	lynx*)
+		os=lynxos
 		;;
-	-atheos*)
-		os=-atheos
+	mac[0-9]*)
+		os=$(echo "$os" | sed -e 's|mac|macos|')
 		;;
-	-syllable*)
-		os=-syllable
+	opened*)
+		os=openedition
 		;;
-	-386bsd)
-		os=-bsd
+	os400*)
+		os=os400
 		;;
-	-ctix* | -uts*)
-		os=-sysv
+	sunos5*)
+		os=$(echo "$os" | sed -e 's|sunos5|solaris2|')
 		;;
-	-nova*)
-		os=-rtmk-nova
+	sunos6*)
+		os=$(echo "$os" | sed -e 's|sunos6|solaris3|')
 		;;
-	-ns2)
-		os=-nextstep2
+	wince*)
+		os=wince
 		;;
-	-nsk*)
-		os=-nsk
+	utek*)
+		os=bsd
 		;;
-	# Preserve the version number of sinix5.
-	-sinix5.*)
-		os=`echo $os | sed -e 's|sinix|sysv|'`
+	dynix*)
+		os=bsd
+		;;
+	acis*)
+		os=aos
+		;;
+	atheos*)
+		os=atheos
+		;;
+	syllable*)
+		os=syllable
+		;;
+	386bsd)
+		os=bsd
+		;;
+	ctix* | uts*)
+		os=sysv
+		;;
+	nova*)
+		os=rtmk-nova
 		;;
-	-sinix*)
-		os=-sysv4
+	ns2)
+		os=nextstep2
 		;;
-	-tpf*)
-		os=-tpf
+	# Preserve the version number of sinix5.
+	sinix5.*)
+		os=$(echo $os | sed -e 's|sinix|sysv|')
 		;;
-	-triton*)
-		os=-sysv3
+	sinix*)
+		os=sysv4
 		;;
-	-oss*)
-		os=-sysv3
+	tpf*)
+		os=tpf
 		;;
-	-svr4*)
-		os=-sysv4
+	triton*)
+		os=sysv3
 		;;
-	-svr3)
-		os=-sysv3
+	oss*)
+		os=sysv3
 		;;
-	-sysvr4)
-		os=-sysv4
+	svr4*)
+		os=sysv4
 		;;
-	# This must come after -sysvr4.
-	-sysv*)
+	svr3)
+		os=sysv3
 		;;
-	-ose*)
-		os=-ose
+	sysvr4)
+		os=sysv4
 		;;
-	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-		os=-mint
+	ose*)
+		os=ose
 		;;
-	-zvmoe)
-		os=-zvmoe
+	*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
+		os=mint
 		;;
-	-dicos*)
-		os=-dicos
+	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 @@ else
 # 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*)
 				vendor=ibm
 				;;
-			-os400*)
+			s390-* | s390x-*)
 				vendor=ibm
 				;;
-			-ptx*)
+			*-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/polly/lib/External/isl/configure b/polly/lib/External/isl/configure
index 211a6487654f6..63f8c4d965834 100755
--- a/polly/lib/External/isl/configure
+++ b/polly/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 at googlegroups.com>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # 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 at googlegroups.com'
 PACKAGE_URL=''
 
@@ -790,7 +790,6 @@ infodir
 docdir
 oldincludedir
 includedir
-runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -888,7 +887,6 @@ datadir='${datarootdir}'
 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 @@ do
   | -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 @@ fi
 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 @@ if test "$ac_init_help" = "long"; then
   # 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 @@ Fine tuning of the installation directories:
   --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 @@ fi
 
 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 @@ fi
 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 @@ cat >config.log <<_ACEOF
 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 @@ program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
 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 @@ fi
 
 # Define the identity of the package.
  PACKAGE='isl'
- VERSION='0.23'
+ VERSION='0.24'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3372,7 +3355,7 @@ fi
 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 @@ esac
 
 
 
-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 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   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 @@ esac
 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 @@ for ac_symprfx in "" "_"; do
   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 @@ _LT_EOF
   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 @@ int forced_loaded() { return 2;}
 _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 @@ esac
 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_static=
 	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 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
 
   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 @@ _LT_EOF
 	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 @@ _LT_EOF
       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 @@ _LT_EOF
 	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 @@ fi
 
     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
           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 @@ $as_echo "$lt_cv_irix_exported_symbol" >&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 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       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 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
 	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 @@ cygwin* | mingw* | pw32* | cegcc*)
     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 @@ cygwin* | mingw* | pw32* | cegcc*)
     ;;
 
   *)
-    # 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 @@ fi
   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 @@ striplib=
 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
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+      ;;
+    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
+      fi
+      ;;
+    *)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-    ;;
-  esac
+      ;;
+    esac
+  fi
 fi
 
 
@@ -16439,7 +16432,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
       # 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 @@ fi
 
       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 @@ fi
 	  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 @@ fi
             # 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 @@ fi
 	    # 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 @@ fi
 	      # 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 @@ fi
 	        # 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 @@ fi
 	        # 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 @@ lt_prog_compiler_static_CXX=
 	    ;;
 	esac
 	;;
-      netbsd* | netbsdelf*-gnu)
+      netbsd*)
 	;;
       *qnx* | *nto*)
         # QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -18301,7 +18295,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     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 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
-    cl*)
+    cl* | icl*)
       exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
       ;;
     *)
@@ -18318,9 +18312,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
       ;;
     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 @@ cygwin* | mingw* | pw32* | cegcc*)
     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 @@ cygwin* | mingw* | pw32* | cegcc*)
     ;;
 
   *)
-    # 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 @@ fi
   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 @@ $as_echo_n "checking for $am_display_PYTHON version... " >&6; }
 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 @@ else
   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 @@ else
   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 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # 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 @@ _ACEOF
 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 @@ want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
 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 @@ want_nocaseglob \
 DLLTOOL \
 sharedlib_from_linklib_cmd \
 AR \
-AR_FLAGS \
 archiver_list_spec \
 STRIP \
 RANLIB \
@@ -23071,7 +23050,9 @@ $as_echo X/"$am_mf" |
     { { $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 @@ sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
 # 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/polly/lib/External/isl/configure.ac b/polly/lib/External/isl/configure.ac
index 0e28a8cc14df9..f082ed40f80c9 100644
--- a/polly/lib/External/isl/configure.ac
+++ b/polly/lib/External/isl/configure.ac
@@ -1,10 +1,10 @@
-AC_INIT([isl], [0.23], [isl-development at googlegroups.com])
+AC_INIT([isl], [0.24], [isl-development at 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(IMATH_FOR_MP, test x$with_int = ximath -o x$with_int = ximath-32)
 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/polly/lib/External/isl/cpp/cpp-checked.h.pre b/polly/lib/External/isl/cpp/cpp-checked.h.pre
deleted file mode 100644
index 988bedbd81460..0000000000000
--- a/polly/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/polly/lib/External/isl/cpp/cpp-checked.h.top b/polly/lib/External/isl/cpp/cpp-checked.h.top
index d33ee35256cdd..be29b971b9b01 100644
--- a/polly/lib/External/isl/cpp/cpp-checked.h.top
+++ b/polly/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/polly/lib/External/isl/cpp/cpp.h.pre b/polly/lib/External/isl/cpp/cpp.h.pre
deleted file mode 100644
index 1ac70c597603e..0000000000000
--- a/polly/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/polly/lib/External/isl/cpp/cpp.h.top b/polly/lib/External/isl/cpp/cpp.h.top
index 793c0ef027e38..15282b129a575 100644
--- a/polly/lib/External/isl/cpp/cpp.h.top
+++ b/polly/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/polly/lib/External/isl/cpp/typed_cpp.h.bot b/polly/lib/External/isl/cpp/typed_cpp.h.bot
new file mode 100644
index 0000000000000..af20081f181d2
--- /dev/null
+++ b/polly/lib/External/isl/cpp/typed_cpp.h.bot
@@ -0,0 +1,5 @@
+
+} // namespace typed
+} // namespace isl
+
+#endif /* ISL_TYPED_CPP */

diff  --git a/polly/lib/External/isl/cpp/typed_cpp.h.top b/polly/lib/External/isl/cpp/typed_cpp.h.top
new file mode 100644
index 0000000000000..d89eb4102ca09
--- /dev/null
+++ b/polly/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/polly/lib/External/isl/depcomp b/polly/lib/External/isl/depcomp
index 65cbf7093a1e4..6b391623c4bf0 100755
--- a/polly/lib/External/isl/depcomp
+++ b/polly/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/polly/lib/External/isl/doc/Makefile.in b/polly/lib/External/isl/doc/Makefile.in
index 5efda3ad08b90..36dda7d180b49 100644
--- a/polly/lib/External/isl/doc/Makefile.in
+++ b/polly/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 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@

diff  --git a/polly/lib/External/isl/doc/mypod2latex b/polly/lib/External/isl/doc/mypod2latex
index 4583bd772d26e..b11c0593d0154 100755
--- a/polly/lib/External/isl/doc/mypod2latex
+++ b/polly/lib/External/isl/doc/mypod2latex
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl
+#!/usr/bin/perl
 
 use strict;
 use Pod::LaTeX;

diff  --git a/polly/lib/External/isl/doc/user.pod b/polly/lib/External/isl/doc/user.pod
index 6d3d9a5f29e14..743e8815f9b35 100644
--- a/polly/lib/External/isl/doc/user.pod
+++ b/polly/lib/External/isl/doc/user.pod
@@ -1197,6 +1197,7 @@ C<isl_dim_out> (only for relations), C<isl_dim_set>
 	#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 @@ C<isl_dim_out> (only for relations), C<isl_dim_set>
 	#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 @@ The identifiers or names of entire spaces may be set or read off
 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 @@ using the following functions.
 	__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 @@ using the following functions.
 		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 @@ using the following functions.
 	__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 @@ using the following functions.
 	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 @@ using the following functions.
 	__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 @@ Similarly for the other pair of functions.
 
 =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 @@ than the first C<n> dimensions in the range.
 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 @@ using the following functions.
 		__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 @@ space.
 	#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 @@ involve any NaN.
 	#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 @@ involve any NaN.
 		__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 @@ of zero affine expressions.
 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 @@ Points can be copied or freed using
 	__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 @@ a specified dimension on a given domain can be created using
 	#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 @@ a specified dimension on a given domain can be created using
 	__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 @@ a specified dimension on a given domain can be created using
 
 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 @@ using the following functions.
 	#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 @@ the identity function is created in that space.
 	__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 @@ the identity function is created in that space.
 	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 @@ projection operations in L</"Unary Operations">.
 	#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 @@ then this space also needs to be a set space.
 	__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 @@ universe cell.
 	__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 @@ created from a multiple expression.
 	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 @@ be used to perform these conversions when they are possible.
 
 	#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 @@ created using the following functions.
 	__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 @@ created using the following functions.
 	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 @@ expression is known to be defined over a single universe domain.
 	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 @@ then create a piecewise expression over a universe domain.
 	__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 @@ then create a piecewise expression over a universe domain.
 	__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 @@ then create a piecewise expression over a given domain.
 	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 @@ position of a piecewise multiple expression can be extracted
 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 @@ The reverse conversion is exact.
 	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 @@ can be created using the following functions.
 
 	#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 @@ all set dimensions.
 
 =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 @@ can be found then assign C<1> to C<*modulo> and C<1> to C<*residue>.
 	__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 @@ If no more specific information can be found, then the stride
 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 @@ requires that the input is non-empty and involves only a single
 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 @@ range space.
 	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 @@ Here we take lists of C<isl_set>s as an example.
 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 @@ Lists can be created, copied, modified and freed using the following functions.
 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 @@ Lists can be inspected using the following functions.
 		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 @@ in isl format.
 	__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/polly/lib/External/isl/include/isl/aff.h b/polly/lib/External/isl/include/isl/aff.h
index ba7702544bf59..cfa0851429dfe 100644
--- a/polly/lib/External/isl/include/isl/aff.h
+++ b/polly/lib/External/isl/include/isl/aff.h
@@ -19,6 +19,8 @@ extern "C" {
 
 __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_space(__isl_take isl_space *space);
 __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_bool isl_pw_aff_isa_aff(__isl_keep isl_pw_aff *pa);
 __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_give isl_multi_aff *isl_multi_aff_from_aff(__isl_take isl_aff *aff);
 __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_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space);
 __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_bool isl_pw_multi_aff_involves_param_id(__isl_keep isl_pw_multi_aff *pma,
 	__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 @@ isl_bool isl_pw_multi_aff_has_tuple_name(__isl_keep isl_pw_multi_aff *pma,
 	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_empty(__isl_take isl_space *space)
 __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_export
 __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_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_aff(
 __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_ctx *isl_union_pw_multi_aff_get_ctx(
 __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_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_subtract_domain(
 	__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_printer *isl_printer_print_union_pw_multi_aff(
 
 __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 @@ uint32_t isl_multi_pw_aff_get_hash(__isl_keep isl_multi_pw_aff *mpa);
 
 __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 @@ __isl_give isl_multi_pw_aff *isl_multi_pw_aff_move_dims(
 	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_give isl_union_pw_aff *isl_union_pw_aff_empty(
 	__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_DROP_DIMS(union_pw_aff)
 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_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_union_add(
 	__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 @@ __isl_give isl_printer *isl_printer_print_multi_union_pw_aff(
 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/polly/lib/External/isl/include/isl/cpp-checked-conversion.h b/polly/lib/External/isl/include/isl/cpp-checked-conversion.h
index 20e422ea8084d..2575ce542c192 100644
--- a/polly/lib/External/isl/include/isl/cpp-checked-conversion.h
+++ b/polly/lib/External/isl/include/isl/cpp-checked-conversion.h
@@ -382,6 +382,14 @@ map uncheck(checked::map obj) {
 	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/polly/lib/External/isl/include/isl/cpp-checked.h b/polly/lib/External/isl/include/isl/cpp-checked.h
index 31922251b01fd..c97cdb2dc4cc1 100644
--- a/polly/lib/External/isl/include/isl/cpp-checked.h
+++ b/polly/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 @@ inline size manage(isl_size val)
 }
 } // 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 fixed_box;
 class id;
 class id_list;
 class map;
+class map_list;
 class multi_aff;
 class multi_id;
 class multi_pw_aff;
@@ -318,35 +319,158 @@ class aff {
   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::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::val constant_val() const;
-  inline isl::checked::val get_constant_val() 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 @@ class aff_list {
   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 @@ class aff_list {
   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 @@ class ast_build {
   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 @@ class ast_node {
   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 @@ class ast_node_for : public ast_node {
   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 @@ class ast_node_if : public ast_node {
   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 @@ class ast_node_list {
   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 @@ class basic_map {
 
   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 @@ class basic_set {
 
   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 @@ class fixed_box {
   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 @@ class id {
 
   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 @@ class id_list {
   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 @@ class id_list {
 
   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 @@ class map {
 
   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 @@ class map {
   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 @@ class map {
   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 @@ class multi_aff {
   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;
+  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::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 isl::checked::aff at(int pos) const;
-  inline isl::checked::aff get_at(int pos) 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 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 @@ class multi_aff {
   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 @@ class multi_id {
   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 @@ class multi_pw_aff {
   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 @@ class multi_pw_aff {
   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::multi_pw_aff sub(isl::checked::multi_pw_aff multi2) 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 @@ class multi_union_pw_aff {
   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 @@ class multi_union_pw_aff {
   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 @@ class multi_val {
   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 @@ class multi_val {
   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 @@ class point {
   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 @@ class pw_aff {
   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 @@ class pw_aff {
   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 @@ class pw_aff_list {
   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 @@ class pw_aff_list {
   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 @@ class pw_multi_aff {
   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 @@ class pw_multi_aff_list {
   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 @@ class pw_multi_aff_list {
   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 @@ class schedule {
   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 @@ class schedule_constraints {
   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 @@ class schedule_constraints {
   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 @@ class schedule_node {
   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 @@ class schedule_node {
   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 @@ class schedule_node_band : public schedule_node {
   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 @@ class set {
 
   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 @@ class set {
   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 @@ class space {
 
   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 @@ class union_map {
   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 @@ class union_map {
   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 @@ class union_map {
   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 @@ class union_map {
   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 @@ class union_pw_aff {
   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 @@ class union_pw_aff_list {
   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 @@ class union_pw_aff_list {
   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 @@ class union_pw_multi_aff {
 
   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 @@ class union_pw_multi_aff {
   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 @@ class union_set {
 
   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 @@ class union_set {
   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 @@ class union_set {
   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 @@ class union_set_list {
   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 @@ class union_set_list {
   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 @@ class val {
   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 @@ class val {
   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 @@ class val {
   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 @@ class val_list {
   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 @@ class val_list {
 
   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,963 +4300,799 @@ isl::checked::aff aff::add(isl::checked::aff aff2) const
   return manage(res);
 }
 
-isl::checked::aff aff::add_constant(isl::checked::val v) const
+isl::checked::multi_aff aff::add(const isl::checked::multi_aff &multi2) const
 {
-  auto res = isl_aff_add_constant_val(copy(), v.release());
-  return manage(res);
+  return isl::checked::multi_aff(*this).add(multi2);
 }
 
-isl::checked::aff aff::add_constant(long v) const
+isl::checked::multi_pw_aff aff::add(const isl::checked::multi_pw_aff &multi2) const
 {
-  return this->add_constant(isl::checked::val(ctx(), v));
+  return isl::checked::pw_aff(*this).add(multi2);
 }
 
-isl::checked::basic_set aff::bind(isl::checked::id id) const
+isl::checked::multi_union_pw_aff aff::add(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  auto res = isl_aff_bind_id(copy(), id.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).add(multi2);
 }
 
-isl::checked::basic_set aff::bind(const std::string &id) const
+isl::checked::pw_aff aff::add(const isl::checked::pw_aff &pwaff2) const
 {
-  return this->bind(isl::checked::id(ctx(), id));
+  return isl::checked::pw_aff(*this).add(pwaff2);
 }
 
-isl::checked::aff aff::ceil() const
+isl::checked::pw_multi_aff aff::add(const isl::checked::pw_multi_aff &pma2) const
 {
-  auto res = isl_aff_ceil(copy());
-  return manage(res);
+  return isl::checked::pw_aff(*this).add(pma2);
 }
 
-isl::checked::aff aff::div(isl::checked::aff aff2) const
+isl::checked::union_pw_aff aff::add(const isl::checked::union_pw_aff &upa2) const
 {
-  auto res = isl_aff_div(copy(), aff2.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).add(upa2);
 }
 
-isl::checked::set aff::eq_set(isl::checked::aff aff2) const
+isl::checked::union_pw_multi_aff aff::add(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_aff_eq_set(copy(), aff2.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).add(upma2);
 }
 
-isl::checked::val aff::eval(isl::checked::point pnt) const
+isl::checked::aff aff::add_constant(isl::checked::val v) const
 {
-  auto res = isl_aff_eval(copy(), pnt.release());
+  auto res = isl_aff_add_constant_val(copy(), v.release());
   return manage(res);
 }
 
-isl::checked::aff aff::floor() const
+isl::checked::aff aff::add_constant(long v) const
 {
-  auto res = isl_aff_floor(copy());
-  return manage(res);
+  return this->add_constant(isl::checked::val(ctx(), v));
 }
 
-isl::checked::set aff::ge_set(isl::checked::aff aff2) const
+isl::checked::multi_aff aff::add_constant(const isl::checked::multi_val &mv) const
 {
-  auto res = isl_aff_ge_set(copy(), aff2.release());
-  return manage(res);
+  return isl::checked::multi_aff(*this).add_constant(mv);
 }
 
-isl::checked::val aff::constant_val() const
+isl::checked::union_pw_multi_aff aff::apply(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_aff_get_constant_val(get());
-  return manage(res);
+  return isl::checked::pw_aff(*this).apply(upma2);
 }
 
-isl::checked::val aff::get_constant_val() const
+isl::checked::aff aff::as_aff() const
 {
-  return constant_val();
+  return isl::checked::pw_aff(*this).as_aff();
 }
 
-isl::checked::aff aff::gist(isl::checked::set context) const
+isl::checked::map aff::as_map() const
 {
-  auto res = isl_aff_gist(copy(), context.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).as_map();
 }
 
-isl::checked::set aff::gt_set(isl::checked::aff aff2) const
+isl::checked::multi_aff aff::as_multi_aff() const
 {
-  auto res = isl_aff_gt_set(copy(), aff2.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).as_multi_aff();
 }
 
-boolean aff::is_cst() const
+isl::checked::multi_union_pw_aff aff::as_multi_union_pw_aff() const
 {
-  auto res = isl_aff_is_cst(get());
-  return manage(res);
+  return isl::checked::pw_aff(*this).as_multi_union_pw_aff();
 }
 
-isl::checked::set aff::le_set(isl::checked::aff aff2) const
+isl::checked::pw_multi_aff aff::as_pw_multi_aff() const
 {
-  auto res = isl_aff_le_set(copy(), aff2.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).as_pw_multi_aff();
 }
 
-isl::checked::set aff::lt_set(isl::checked::aff aff2) const
+isl::checked::set aff::as_set() const
 {
-  auto res = isl_aff_lt_set(copy(), aff2.release());
-  return manage(res);
+  return isl::checked::multi_aff(*this).as_set();
 }
 
-isl::checked::aff aff::mod(isl::checked::val mod) const
+isl::checked::union_map aff::as_union_map() const
 {
-  auto res = isl_aff_mod_val(copy(), mod.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).as_union_map();
 }
 
-isl::checked::aff aff::mod(long mod) const
+isl::checked::aff aff::at(int pos) const
 {
-  return this->mod(isl::checked::val(ctx(), mod));
+  return isl::checked::multi_aff(*this).at(pos);
 }
 
-isl::checked::aff aff::mul(isl::checked::aff aff2) const
+isl::checked::basic_set aff::bind(isl::checked::id id) const
 {
-  auto res = isl_aff_mul(copy(), aff2.release());
+  auto res = isl_aff_bind_id(copy(), id.release());
   return manage(res);
 }
 
-isl::checked::set aff::ne_set(isl::checked::aff aff2) const
+isl::checked::basic_set aff::bind(const std::string &id) const
 {
-  auto res = isl_aff_ne_set(copy(), aff2.release());
-  return manage(res);
+  return this->bind(isl::checked::id(ctx(), id));
 }
 
-isl::checked::aff aff::neg() const
+isl::checked::basic_set aff::bind(const isl::checked::multi_id &tuple) const
 {
-  auto res = isl_aff_neg(copy());
-  return manage(res);
+  return isl::checked::multi_aff(*this).bind(tuple);
 }
 
-isl::checked::aff aff::pullback(isl::checked::multi_aff ma) const
+isl::checked::pw_aff aff::bind_domain(const isl::checked::multi_id &tuple) const
 {
-  auto res = isl_aff_pullback_multi_aff(copy(), ma.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).bind_domain(tuple);
 }
 
-isl::checked::aff aff::scale(isl::checked::val v) const
+isl::checked::pw_aff aff::bind_domain_wrapped_domain(const isl::checked::multi_id &tuple) const
 {
-  auto res = isl_aff_scale_val(copy(), v.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).bind_domain_wrapped_domain(tuple);
 }
 
-isl::checked::aff aff::scale(long v) const
+isl::checked::aff aff::ceil() const
 {
-  return this->scale(isl::checked::val(ctx(), v));
+  auto res = isl_aff_ceil(copy());
+  return manage(res);
 }
 
-isl::checked::aff aff::scale_down(isl::checked::val v) const
+isl::checked::pw_aff aff::coalesce() const
 {
-  auto res = isl_aff_scale_down_val(copy(), v.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).coalesce();
 }
 
-isl::checked::aff aff::scale_down(long v) const
+isl::checked::pw_aff aff::cond(const isl::checked::pw_aff &pwaff_true, const isl::checked::pw_aff &pwaff_false) const
 {
-  return this->scale_down(isl::checked::val(ctx(), v));
+  return isl::checked::pw_aff(*this).cond(pwaff_true, pwaff_false);
 }
 
-isl::checked::aff aff::sub(isl::checked::aff aff2) const
+isl::checked::multi_val aff::constant_multi_val() const
 {
-  auto res = isl_aff_sub(copy(), aff2.release());
-  return manage(res);
+  return isl::checked::multi_aff(*this).constant_multi_val();
 }
 
-isl::checked::aff aff::unbind_params_insert_domain(isl::checked::multi_id domain) const
+isl::checked::val aff::constant_val() const
 {
-  auto res = isl_aff_unbind_params_insert_domain(copy(), domain.release());
+  auto res = isl_aff_get_constant_val(get());
   return manage(res);
 }
 
-isl::checked::aff aff::zero_on_domain(isl::checked::space space)
+isl::checked::val aff::get_constant_val() const
 {
-  auto res = isl_aff_zero_on_domain_space(space.release());
-  return manage(res);
+  return constant_val();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const aff &obj)
+isl::checked::aff aff::div(isl::checked::aff aff2) const
 {
-  char *str = isl_aff_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  auto res = isl_aff_div(copy(), aff2.release());
+  return manage(res);
 }
 
-// implementations for isl::aff_list
-aff_list manage(__isl_take isl_aff_list *ptr) {
-  return aff_list(ptr);
-}
-aff_list manage_copy(__isl_keep isl_aff_list *ptr) {
-  ptr = isl_aff_list_copy(ptr);
-  return aff_list(ptr);
+isl::checked::pw_aff aff::div(const isl::checked::pw_aff &pa2) const
+{
+  return isl::checked::pw_aff(*this).div(pa2);
 }
 
-aff_list::aff_list()
-    : ptr(nullptr) {}
-
-aff_list::aff_list(const aff_list &obj)
-    : ptr(nullptr)
+isl::checked::set aff::domain() const
 {
-  ptr = obj.copy();
+  return isl::checked::pw_aff(*this).domain();
 }
 
-aff_list::aff_list(__isl_take isl_aff_list *ptr)
-    : ptr(ptr) {}
-
-aff_list::aff_list(isl::checked::ctx ctx, int n)
+isl::checked::set aff::eq_set(isl::checked::aff aff2) const
 {
-  auto res = isl_aff_list_alloc(ctx.release(), n);
-  ptr = res;
+  auto res = isl_aff_eq_set(copy(), aff2.release());
+  return manage(res);
 }
 
-aff_list::aff_list(isl::checked::aff el)
+isl::checked::set aff::eq_set(const isl::checked::pw_aff &pwaff2) const
 {
-  auto res = isl_aff_list_from_aff(el.release());
-  ptr = res;
+  return isl::checked::pw_aff(*this).eq_set(pwaff2);
 }
 
-aff_list &aff_list::operator=(aff_list obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::val aff::eval(isl::checked::point pnt) const
+{
+  auto res = isl_aff_eval(copy(), pnt.release());
+  return manage(res);
 }
 
-aff_list::~aff_list() {
-  if (ptr)
-    isl_aff_list_free(ptr);
+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_give isl_aff_list *aff_list::copy() const & {
-  return isl_aff_list_copy(ptr);
+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_keep isl_aff_list *aff_list::get() const {
-  return ptr;
+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_give isl_aff_list *aff_list::release() {
-  isl_aff_list *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+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);
 }
 
-bool aff_list::is_null() const {
-  return ptr == nullptr;
+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::ctx aff_list::ctx() const {
-  return isl::checked::ctx(isl_aff_list_get_ctx(ptr));
+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_list aff_list::add(isl::checked::aff el) const
+isl::checked::aff aff::floor() const
 {
-  auto res = isl_aff_list_add(copy(), el.release());
+  auto res = isl_aff_floor(copy());
   return manage(res);
 }
 
-isl::checked::aff_list aff_list::clear() const
+stat aff::foreach_piece(const std::function<stat(isl::checked::set, isl::checked::multi_aff)> &fn) const
 {
-  auto res = isl_aff_list_clear(copy());
-  return manage(res);
+  return isl::checked::pw_aff(*this).foreach_piece(fn);
 }
 
-isl::checked::aff_list aff_list::concat(isl::checked::aff_list list2) const
+isl::checked::set aff::ge_set(isl::checked::aff aff2) const
 {
-  auto res = isl_aff_list_concat(copy(), list2.release());
+  auto res = isl_aff_ge_set(copy(), aff2.release());
   return manage(res);
 }
 
-isl::checked::aff_list aff_list::drop(unsigned int first, unsigned int n) const
+isl::checked::set aff::ge_set(const isl::checked::pw_aff &pwaff2) const
 {
-  auto res = isl_aff_list_drop(copy(), first, n);
-  return manage(res);
+  return isl::checked::pw_aff(*this).ge_set(pwaff2);
 }
 
-stat aff_list::foreach(const std::function<stat(isl::checked::aff)> &fn) const
+isl::checked::aff aff::gist(isl::checked::set context) const
 {
-  struct fn_data {
-    std::function<stat(isl::checked::aff)> func;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_aff *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_aff_list_foreach(get(), fn_lambda, &fn_data);
+  auto res = isl_aff_gist(copy(), context.release());
   return manage(res);
 }
 
-isl::checked::aff aff_list::at(int index) const
+isl::checked::union_pw_aff aff::gist(const isl::checked::union_set &context) const
 {
-  auto res = isl_aff_list_get_at(get(), index);
-  return manage(res);
+  return isl::checked::pw_aff(*this).gist(context);
 }
 
-isl::checked::aff aff_list::get_at(int index) const
+isl::checked::aff aff::gist(const isl::checked::basic_set &context) const
 {
-  return at(index);
+  return this->gist(isl::checked::set(context));
 }
 
-isl::checked::aff_list aff_list::insert(unsigned int pos, isl::checked::aff el) const
+isl::checked::aff aff::gist(const isl::checked::point &context) const
 {
-  auto res = isl_aff_list_insert(copy(), pos, el.release());
-  return manage(res);
+  return this->gist(isl::checked::set(context));
 }
 
-class size aff_list::size() const
+isl::checked::set aff::gt_set(isl::checked::aff aff2) const
 {
-  auto res = isl_aff_list_size(get());
+  auto res = isl_aff_gt_set(copy(), aff2.release());
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const aff_list &obj)
+isl::checked::set aff::gt_set(const isl::checked::pw_aff &pwaff2) const
 {
-  char *str = isl_aff_list_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_aff(*this).gt_set(pwaff2);
 }
 
-// implementations for isl::ast_build
-ast_build manage(__isl_take isl_ast_build *ptr) {
-  return ast_build(ptr);
-}
-ast_build manage_copy(__isl_keep isl_ast_build *ptr) {
-  ptr = isl_ast_build_copy(ptr);
-  return ast_build(ptr);
+boolean aff::has_range_tuple_id() const
+{
+  return isl::checked::multi_aff(*this).has_range_tuple_id();
 }
 
-ast_build::ast_build()
-    : ptr(nullptr) {}
-
-ast_build::ast_build(const ast_build &obj)
-    : ptr(nullptr)
+isl::checked::multi_aff aff::identity() const
 {
-  ptr = obj.copy();
-  copy_callbacks(obj);
+  return isl::checked::multi_aff(*this).identity();
 }
 
-ast_build::ast_build(__isl_take isl_ast_build *ptr)
-    : ptr(ptr) {}
-
-ast_build::ast_build(isl::checked::ctx ctx)
+isl::checked::pw_aff aff::insert_domain(const isl::checked::space &domain) const
 {
-  auto res = isl_ast_build_alloc(ctx.release());
-  ptr = res;
+  return isl::checked::pw_aff(*this).insert_domain(domain);
 }
 
-ast_build &ast_build::operator=(ast_build obj) {
-  std::swap(this->ptr, obj.ptr);
-  copy_callbacks(obj);
-  return *this;
+isl::checked::pw_aff aff::intersect_domain(const isl::checked::set &set) const
+{
+  return isl::checked::pw_aff(*this).intersect_domain(set);
 }
 
-ast_build::~ast_build() {
-  if (ptr)
-    isl_ast_build_free(ptr);
+isl::checked::union_pw_aff aff::intersect_domain(const isl::checked::space &space) const
+{
+  return isl::checked::pw_aff(*this).intersect_domain(space);
 }
 
-__isl_give isl_ast_build *ast_build::copy() const & {
-  return isl_ast_build_copy(ptr);
+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_keep isl_ast_build *ast_build::get() const {
-  return ptr;
+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_give isl_ast_build *ast_build::release() {
-  if (at_each_domain_data)
-    isl_die(ctx().get(), isl_error_invalid, "cannot release object with persistent callbacks", return nullptr);
-  isl_ast_build *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+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);
 }
 
-bool ast_build::is_null() const {
-  return ptr == nullptr;
+isl::checked::pw_aff aff::intersect_params(const isl::checked::set &set) const
+{
+  return isl::checked::pw_aff(*this).intersect_params(set);
 }
 
-isl::checked::ctx ast_build::ctx() const {
-  return isl::checked::ctx(isl_ast_build_get_ctx(ptr));
+boolean aff::involves_locals() const
+{
+  return isl::checked::multi_aff(*this).involves_locals();
 }
 
-ast_build &ast_build::copy_callbacks(const ast_build &obj)
+boolean aff::involves_nan() const
 {
-  at_each_domain_data = obj.at_each_domain_data;
-  return *this;
+  return isl::checked::multi_aff(*this).involves_nan();
 }
 
-isl_ast_node *ast_build::at_each_domain(isl_ast_node *arg_0, isl_ast_build *arg_1, void *arg_2)
+boolean aff::involves_param(const isl::checked::id &id) const
 {
-  auto *data = static_cast<struct at_each_domain_data *>(arg_2);
-  auto ret = (data->func)(manage(arg_0), manage_copy(arg_1));
-  return ret.release();
+  return isl::checked::pw_aff(*this).involves_param(id);
 }
 
-void ast_build::set_at_each_domain_data(const std::function<isl::checked::ast_node(isl::checked::ast_node, isl::checked::ast_build)> &fn)
+boolean aff::involves_param(const std::string &id) const
 {
-  at_each_domain_data = std::make_shared<struct at_each_domain_data>();
-  at_each_domain_data->func = fn;
-  ptr = isl_ast_build_set_at_each_domain(ptr, &at_each_domain, at_each_domain_data.get());
+  return this->involves_param(isl::checked::id(ctx(), id));
 }
 
-isl::checked::ast_build ast_build::set_at_each_domain(const std::function<isl::checked::ast_node(isl::checked::ast_node, isl::checked::ast_build)> &fn) const
+boolean aff::involves_param(const isl::checked::id_list &list) const
 {
-  auto copy = *this;
-  copy.set_at_each_domain_data(fn);
-  return copy;
+  return isl::checked::pw_aff(*this).involves_param(list);
 }
 
-isl::checked::ast_expr ast_build::access_from(isl::checked::multi_pw_aff mpa) const
+boolean aff::is_cst() const
 {
-  auto res = isl_ast_build_access_from_multi_pw_aff(get(), mpa.release());
+  auto res = isl_aff_is_cst(get());
   return manage(res);
 }
 
-isl::checked::ast_expr ast_build::access_from(isl::checked::pw_multi_aff pma) const
+boolean aff::isa_aff() const
 {
-  auto res = isl_ast_build_access_from_pw_multi_aff(get(), pma.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).isa_aff();
 }
 
-isl::checked::ast_expr ast_build::call_from(isl::checked::multi_pw_aff mpa) const
+boolean aff::isa_multi_aff() const
 {
-  auto res = isl_ast_build_call_from_multi_pw_aff(get(), mpa.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).isa_multi_aff();
 }
 
-isl::checked::ast_expr ast_build::call_from(isl::checked::pw_multi_aff pma) const
+boolean aff::isa_pw_multi_aff() const
 {
-  auto res = isl_ast_build_call_from_pw_multi_aff(get(), pma.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).isa_pw_multi_aff();
 }
 
-isl::checked::ast_expr ast_build::expr_from(isl::checked::pw_aff pa) const
+isl::checked::set aff::le_set(isl::checked::aff aff2) const
 {
-  auto res = isl_ast_build_expr_from_pw_aff(get(), pa.release());
+  auto res = isl_aff_le_set(copy(), aff2.release());
   return manage(res);
 }
 
-isl::checked::ast_expr ast_build::expr_from(isl::checked::set set) const
+isl::checked::set aff::le_set(const isl::checked::pw_aff &pwaff2) const
 {
-  auto res = isl_ast_build_expr_from_set(get(), set.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).le_set(pwaff2);
 }
 
-isl::checked::ast_build ast_build::from_context(isl::checked::set set)
+isl::checked::aff_list aff::list() const
 {
-  auto res = isl_ast_build_from_context(set.release());
-  return manage(res);
+  return isl::checked::multi_aff(*this).list();
 }
 
-isl::checked::union_map ast_build::schedule() const
+isl::checked::set aff::lt_set(isl::checked::aff aff2) const
 {
-  auto res = isl_ast_build_get_schedule(get());
+  auto res = isl_aff_lt_set(copy(), aff2.release());
   return manage(res);
 }
 
-isl::checked::union_map ast_build::get_schedule() const
+isl::checked::set aff::lt_set(const isl::checked::pw_aff &pwaff2) const
 {
-  return schedule();
+  return isl::checked::pw_aff(*this).lt_set(pwaff2);
 }
 
-isl::checked::ast_node ast_build::node_from(isl::checked::schedule schedule) const
+isl::checked::multi_pw_aff aff::max(const isl::checked::multi_pw_aff &multi2) const
 {
-  auto res = isl_ast_build_node_from_schedule(get(), schedule.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).max(multi2);
 }
 
-isl::checked::ast_node ast_build::node_from_schedule_map(isl::checked::union_map schedule) const
+isl::checked::pw_aff aff::max(const isl::checked::pw_aff &pwaff2) const
 {
-  auto res = isl_ast_build_node_from_schedule_map(get(), schedule.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).max(pwaff2);
 }
 
-// implementations for isl::ast_expr
-ast_expr manage(__isl_take isl_ast_expr *ptr) {
-  return ast_expr(ptr);
-}
-ast_expr manage_copy(__isl_keep isl_ast_expr *ptr) {
-  ptr = isl_ast_expr_copy(ptr);
-  return ast_expr(ptr);
+isl::checked::multi_val aff::max_multi_val() const
+{
+  return isl::checked::pw_aff(*this).max_multi_val();
 }
 
-ast_expr::ast_expr()
-    : ptr(nullptr) {}
+isl::checked::multi_pw_aff aff::min(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_aff(*this).min(multi2);
+}
 
-ast_expr::ast_expr(const ast_expr &obj)
-    : ptr(nullptr)
+isl::checked::pw_aff aff::min(const isl::checked::pw_aff &pwaff2) const
 {
-  ptr = obj.copy();
+  return isl::checked::pw_aff(*this).min(pwaff2);
 }
 
-ast_expr::ast_expr(__isl_take isl_ast_expr *ptr)
-    : ptr(ptr) {}
+isl::checked::multi_val aff::min_multi_val() const
+{
+  return isl::checked::pw_aff(*this).min_multi_val();
+}
 
-ast_expr &ast_expr::operator=(ast_expr obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::aff aff::mod(isl::checked::val mod) const
+{
+  auto res = isl_aff_mod_val(copy(), mod.release());
+  return manage(res);
 }
 
-ast_expr::~ast_expr() {
-  if (ptr)
-    isl_ast_expr_free(ptr);
+isl::checked::aff aff::mod(long mod) const
+{
+  return this->mod(isl::checked::val(ctx(), mod));
 }
 
-__isl_give isl_ast_expr *ast_expr::copy() const & {
-  return isl_ast_expr_copy(ptr);
+isl::checked::aff aff::mul(isl::checked::aff aff2) const
+{
+  auto res = isl_aff_mul(copy(), aff2.release());
+  return manage(res);
 }
 
-__isl_keep isl_ast_expr *ast_expr::get() const {
-  return ptr;
+isl::checked::pw_aff aff::mul(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).mul(pwaff2);
 }
 
-__isl_give isl_ast_expr *ast_expr::release() {
-  isl_ast_expr *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+class size aff::n_piece() const
+{
+  return isl::checked::pw_aff(*this).n_piece();
 }
 
-bool ast_expr::is_null() const {
-  return ptr == nullptr;
+isl::checked::set aff::ne_set(isl::checked::aff aff2) const
+{
+  auto res = isl_aff_ne_set(copy(), aff2.release());
+  return manage(res);
 }
 
-template <typename T, typename>
-boolean ast_expr::isa_type(T subtype) const
+isl::checked::set aff::ne_set(const isl::checked::pw_aff &pwaff2) const
 {
-  if (is_null())
-    return boolean();
-  return isl_ast_expr_get_type(get()) == subtype;
+  return isl::checked::pw_aff(*this).ne_set(pwaff2);
 }
-template <class T>
-boolean ast_expr::isa() const
+
+isl::checked::aff aff::neg() const
 {
-  return isa_type<decltype(T::type)>(T::type);
+  auto res = isl_aff_neg(copy());
+  return manage(res);
 }
-template <class T>
-T ast_expr::as() const
+
+boolean aff::plain_is_empty() const
 {
- if (isa<T>().is_false())
-    isl_die(ctx().get(), isl_error_invalid, "not an object of the requested subtype", return T());
-  return T(copy());
+  return isl::checked::pw_aff(*this).plain_is_empty();
 }
 
-isl::checked::ctx ast_expr::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+boolean aff::plain_is_equal(const isl::checked::multi_aff &multi2) const
+{
+  return isl::checked::multi_aff(*this).plain_is_equal(multi2);
 }
 
-std::string ast_expr::to_C_str() const
+boolean aff::plain_is_equal(const isl::checked::multi_pw_aff &multi2) const
 {
-  auto res = isl_ast_expr_to_C_str(get());
-  std::string tmp(res);
-  free(res);
-  return tmp;
+  return isl::checked::pw_aff(*this).plain_is_equal(multi2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr &obj)
+boolean aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_aff(*this).plain_is_equal(multi2);
 }
 
-// implementations for isl::ast_expr_id
-ast_expr_id::ast_expr_id()
-    : ast_expr() {}
+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);
+}
 
-ast_expr_id::ast_expr_id(const ast_expr_id &obj)
-    : ast_expr(obj)
+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);
 }
 
-ast_expr_id::ast_expr_id(__isl_take isl_ast_expr *ptr)
-    : ast_expr(ptr) {}
+isl::checked::multi_aff aff::product(const isl::checked::multi_aff &multi2) const
+{
+  return isl::checked::multi_aff(*this).product(multi2);
+}
 
-ast_expr_id &ast_expr_id::operator=(ast_expr_id obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_id::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+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::id ast_expr_id::id() const
+isl::checked::aff aff::pullback(isl::checked::multi_aff ma) const
 {
-  auto res = isl_ast_expr_id_get_id(get());
+  auto res = isl_aff_pullback_multi_aff(copy(), ma.release());
   return manage(res);
 }
 
-isl::checked::id ast_expr_id::get_id() const
+isl::checked::pw_aff aff::pullback(const isl::checked::multi_pw_aff &mpa) const
 {
-  return id();
+  return isl::checked::pw_aff(*this).pullback(mpa);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_id &obj)
+isl::checked::pw_aff aff::pullback(const isl::checked::pw_multi_aff &pma) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_aff(*this).pullback(pma);
 }
 
-// implementations for isl::ast_expr_int
-ast_expr_int::ast_expr_int()
-    : ast_expr() {}
-
-ast_expr_int::ast_expr_int(const ast_expr_int &obj)
-    : ast_expr(obj)
+isl::checked::union_pw_aff aff::pullback(const isl::checked::union_pw_multi_aff &upma) const
 {
+  return isl::checked::pw_aff(*this).pullback(upma);
 }
 
-ast_expr_int::ast_expr_int(__isl_take isl_ast_expr *ptr)
-    : ast_expr(ptr) {}
+isl::checked::aff aff::pullback(const isl::checked::aff &ma) const
+{
+  return this->pullback(isl::checked::multi_aff(ma));
+}
 
-ast_expr_int &ast_expr_int::operator=(ast_expr_int obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::pw_multi_aff_list aff::pw_multi_aff_list() const
+{
+  return isl::checked::pw_aff(*this).pw_multi_aff_list();
 }
 
-isl::checked::ctx ast_expr_int::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+isl::checked::pw_multi_aff aff::range_factor_domain() const
+{
+  return isl::checked::pw_aff(*this).range_factor_domain();
 }
 
-isl::checked::val ast_expr_int::val() const
+isl::checked::pw_multi_aff aff::range_factor_range() const
 {
-  auto res = isl_ast_expr_int_get_val(get());
-  return manage(res);
+  return isl::checked::pw_aff(*this).range_factor_range();
 }
 
-isl::checked::val ast_expr_int::get_val() const
+isl::checked::multi_aff aff::range_product(const isl::checked::multi_aff &multi2) const
 {
-  return val();
+  return isl::checked::multi_aff(*this).range_product(multi2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_int &obj)
+isl::checked::multi_pw_aff aff::range_product(const isl::checked::multi_pw_aff &multi2) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_aff(*this).range_product(multi2);
 }
 
-// implementations for isl::ast_expr_op
-ast_expr_op::ast_expr_op()
-    : ast_expr() {}
+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);
+}
 
-ast_expr_op::ast_expr_op(const ast_expr_op &obj)
-    : ast_expr(obj)
+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);
 }
 
-ast_expr_op::ast_expr_op(__isl_take isl_ast_expr *ptr)
-    : ast_expr(ptr) {}
+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);
+}
 
-ast_expr_op &ast_expr_op::operator=(ast_expr_op obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::id aff::range_tuple_id() const
+{
+  return isl::checked::multi_aff(*this).range_tuple_id();
 }
 
-template <typename T, typename>
-boolean ast_expr_op::isa_type(T subtype) const
+isl::checked::multi_aff aff::reset_range_tuple_id() const
 {
-  if (is_null())
-    return boolean();
-  return isl_ast_expr_op_get_type(get()) == subtype;
+  return isl::checked::multi_aff(*this).reset_range_tuple_id();
 }
-template <class T>
-boolean ast_expr_op::isa() const
+
+isl::checked::aff aff::scale(isl::checked::val v) const
 {
-  return isa_type<decltype(T::type)>(T::type);
+  auto res = isl_aff_scale_val(copy(), v.release());
+  return manage(res);
 }
-template <class T>
-T ast_expr_op::as() const
+
+isl::checked::aff aff::scale(long v) const
 {
- if (isa<T>().is_false())
-    isl_die(ctx().get(), isl_error_invalid, "not an object of the requested subtype", return T());
-  return T(copy());
+  return this->scale(isl::checked::val(ctx(), v));
 }
 
-isl::checked::ctx ast_expr_op::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+isl::checked::multi_aff aff::scale(const isl::checked::multi_val &mv) const
+{
+  return isl::checked::multi_aff(*this).scale(mv);
 }
 
-isl::checked::ast_expr ast_expr_op::arg(int pos) const
+isl::checked::aff aff::scale_down(isl::checked::val v) const
 {
-  auto res = isl_ast_expr_op_get_arg(get(), pos);
+  auto res = isl_aff_scale_down_val(copy(), v.release());
   return manage(res);
 }
 
-isl::checked::ast_expr ast_expr_op::get_arg(int pos) const
+isl::checked::aff aff::scale_down(long v) const
 {
-  return arg(pos);
+  return this->scale_down(isl::checked::val(ctx(), v));
 }
 
-class size ast_expr_op::n_arg() const
+isl::checked::multi_aff aff::scale_down(const isl::checked::multi_val &mv) const
 {
-  auto res = isl_ast_expr_op_get_n_arg(get());
-  return manage(res);
+  return isl::checked::multi_aff(*this).scale_down(mv);
 }
 
-class size ast_expr_op::get_n_arg() const
+isl::checked::multi_aff aff::set_at(int pos, const isl::checked::aff &el) const
 {
-  return n_arg();
+  return isl::checked::multi_aff(*this).set_at(pos, el);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op &obj)
+isl::checked::multi_pw_aff aff::set_at(int pos, const isl::checked::pw_aff &el) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_aff(*this).set_at(pos, el);
 }
 
-// implementations for isl::ast_expr_op_access
-ast_expr_op_access::ast_expr_op_access()
-    : ast_expr_op() {}
-
-ast_expr_op_access::ast_expr_op_access(const ast_expr_op_access &obj)
-    : ast_expr_op(obj)
+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);
 }
 
-ast_expr_op_access::ast_expr_op_access(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_access &ast_expr_op_access::operator=(ast_expr_op_access obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_op_access::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+isl::checked::multi_aff aff::set_range_tuple(const std::string &id) const
+{
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_access &obj)
+class size aff::size() const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::multi_aff(*this).size();
 }
 
-// implementations for isl::ast_expr_op_add
-ast_expr_op_add::ast_expr_op_add()
-    : ast_expr_op() {}
-
-ast_expr_op_add::ast_expr_op_add(const ast_expr_op_add &obj)
-    : ast_expr_op(obj)
+isl::checked::space aff::space() const
 {
+  return isl::checked::multi_aff(*this).space();
 }
 
-ast_expr_op_add::ast_expr_op_add(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_add &ast_expr_op_add::operator=(ast_expr_op_add obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::aff aff::sub(isl::checked::aff aff2) const
+{
+  auto res = isl_aff_sub(copy(), aff2.release());
+  return manage(res);
 }
 
-isl::checked::ctx ast_expr_op_add::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+isl::checked::multi_aff aff::sub(const isl::checked::multi_aff &multi2) const
+{
+  return isl::checked::multi_aff(*this).sub(multi2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_add &obj)
+isl::checked::multi_pw_aff aff::sub(const isl::checked::multi_pw_aff &multi2) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_aff(*this).sub(multi2);
 }
 
-// implementations for isl::ast_expr_op_address_of
-ast_expr_op_address_of::ast_expr_op_address_of()
-    : ast_expr_op() {}
-
-ast_expr_op_address_of::ast_expr_op_address_of(const ast_expr_op_address_of &obj)
-    : ast_expr_op(obj)
+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);
 }
 
-ast_expr_op_address_of::ast_expr_op_address_of(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_address_of &ast_expr_op_address_of::operator=(ast_expr_op_address_of obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::pw_aff aff::sub(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).sub(pwaff2);
 }
 
-isl::checked::ctx ast_expr_op_address_of::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+isl::checked::pw_multi_aff aff::sub(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_aff(*this).sub(pma2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_address_of &obj)
+isl::checked::union_pw_aff aff::sub(const isl::checked::union_pw_aff &upa2) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_aff(*this).sub(upa2);
 }
 
-// implementations for isl::ast_expr_op_and
-ast_expr_op_and::ast_expr_op_and()
-    : ast_expr_op() {}
-
-ast_expr_op_and::ast_expr_op_and(const ast_expr_op_and &obj)
-    : ast_expr_op(obj)
+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);
 }
 
-ast_expr_op_and::ast_expr_op_and(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_and &ast_expr_op_and::operator=(ast_expr_op_and obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::pw_aff aff::subtract_domain(const isl::checked::set &set) const
+{
+  return isl::checked::pw_aff(*this).subtract_domain(set);
 }
 
-isl::checked::ctx ast_expr_op_and::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+isl::checked::union_pw_aff aff::subtract_domain(const isl::checked::space &space) const
+{
+  return isl::checked::pw_aff(*this).subtract_domain(space);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_and &obj)
+isl::checked::union_pw_aff aff::subtract_domain(const isl::checked::union_set &uset) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_aff(*this).subtract_domain(uset);
 }
 
-// implementations for isl::ast_expr_op_and_then
-ast_expr_op_and_then::ast_expr_op_and_then()
-    : ast_expr_op() {}
-
-ast_expr_op_and_then::ast_expr_op_and_then(const ast_expr_op_and_then &obj)
-    : ast_expr_op(obj)
+isl::checked::pw_aff aff::tdiv_q(const isl::checked::pw_aff &pa2) const
 {
+  return isl::checked::pw_aff(*this).tdiv_q(pa2);
 }
 
-ast_expr_op_and_then::ast_expr_op_and_then(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+isl::checked::pw_aff aff::tdiv_r(const isl::checked::pw_aff &pa2) const
+{
+  return isl::checked::pw_aff(*this).tdiv_r(pa2);
+}
 
-ast_expr_op_and_then &ast_expr_op_and_then::operator=(ast_expr_op_and_then obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::aff_list aff::to_list() const
+{
+  auto res = isl_aff_to_list(copy());
+  return manage(res);
 }
 
-isl::checked::ctx ast_expr_op_and_then::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+isl::checked::multi_pw_aff aff::to_multi_pw_aff() const
+{
+  return isl::checked::multi_aff(*this).to_multi_pw_aff();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_and_then &obj)
+isl::checked::multi_union_pw_aff aff::to_multi_union_pw_aff() const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::multi_aff(*this).to_multi_union_pw_aff();
 }
 
-// implementations for isl::ast_expr_op_call
-ast_expr_op_call::ast_expr_op_call()
-    : ast_expr_op() {}
+isl::checked::pw_multi_aff aff::to_pw_multi_aff() const
+{
+  return isl::checked::multi_aff(*this).to_pw_multi_aff();
+}
 
-ast_expr_op_call::ast_expr_op_call(const ast_expr_op_call &obj)
-    : ast_expr_op(obj)
+isl::checked::union_pw_aff aff::to_union_pw_aff() const
 {
+  return isl::checked::pw_aff(*this).to_union_pw_aff();
 }
 
-ast_expr_op_call::ast_expr_op_call(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+isl::checked::union_pw_multi_aff aff::to_union_pw_multi_aff() const
+{
+  return isl::checked::pw_aff(*this).to_union_pw_multi_aff();
+}
 
-ast_expr_op_call &ast_expr_op_call::operator=(ast_expr_op_call obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_op_call::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+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);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_call &obj)
+isl::checked::multi_union_pw_aff aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_aff(*this).union_add(mupa2);
 }
 
-// implementations for isl::ast_expr_op_cond
-ast_expr_op_cond::ast_expr_op_cond()
-    : ast_expr_op() {}
+isl::checked::pw_aff aff::union_add(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).union_add(pwaff2);
+}
 
-ast_expr_op_cond::ast_expr_op_cond(const ast_expr_op_cond &obj)
-    : ast_expr_op(obj)
+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);
 }
 
-ast_expr_op_cond::ast_expr_op_cond(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+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);
+}
 
-ast_expr_op_cond &ast_expr_op_cond::operator=(ast_expr_op_cond obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_op_cond::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+isl::checked::aff aff::zero_on_domain(isl::checked::space space)
+{
+  auto res = isl_aff_zero_on_domain_space(space.release());
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_cond &obj)
+inline std::ostream &operator<<(std::ostream &os, const aff &obj)
 {
-  char *str = isl_ast_expr_to_str(obj.get());
+  char *str = isl_aff_to_str(obj.get());
   if (!str) {
     os.setstate(std::ios_base::badbit);
     return os;
@@ -4257,65 +5102,4680 @@ inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_cond &obj)
   return os;
 }
 
-// implementations for isl::ast_expr_op_div
-ast_expr_op_div::ast_expr_op_div()
-    : ast_expr_op() {}
-
-ast_expr_op_div::ast_expr_op_div(const ast_expr_op_div &obj)
-    : ast_expr_op(obj)
-{
+// implementations for isl::aff_list
+aff_list manage(__isl_take isl_aff_list *ptr) {
+  return aff_list(ptr);
+}
+aff_list manage_copy(__isl_keep isl_aff_list *ptr) {
+  ptr = isl_aff_list_copy(ptr);
+  return aff_list(ptr);
 }
 
-ast_expr_op_div::ast_expr_op_div(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+aff_list::aff_list()
+    : ptr(nullptr) {}
 
-ast_expr_op_div &ast_expr_op_div::operator=(ast_expr_op_div obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+aff_list::aff_list(const aff_list &obj)
+    : ptr(nullptr)
+{
+  ptr = obj.copy();
 }
 
-isl::checked::ctx ast_expr_op_div::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
-}
+aff_list::aff_list(__isl_take isl_aff_list *ptr)
+    : ptr(ptr) {}
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_div &obj)
+aff_list::aff_list(isl::checked::ctx ctx, int n)
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  auto res = isl_aff_list_alloc(ctx.release(), n);
+  ptr = res;
 }
 
-// implementations for isl::ast_expr_op_eq
-ast_expr_op_eq::ast_expr_op_eq()
-    : ast_expr_op() {}
-
-ast_expr_op_eq::ast_expr_op_eq(const ast_expr_op_eq &obj)
-    : ast_expr_op(obj)
+aff_list::aff_list(isl::checked::aff el)
 {
+  auto res = isl_aff_list_from_aff(el.release());
+  ptr = res;
 }
 
-ast_expr_op_eq::ast_expr_op_eq(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+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;
+}
 
-ast_expr_op_eq &ast_expr_op_eq::operator=(ast_expr_op_eq obj) {
+aff_list &aff_list::operator=(aff_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-isl::checked::ctx ast_expr_op_eq::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+aff_list::~aff_list() {
+  if (ptr)
+    isl_aff_list_free(ptr);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_eq &obj)
-{
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
+__isl_give isl_aff_list *aff_list::copy() const & {
+  return isl_aff_list_copy(ptr);
+}
+
+__isl_keep isl_aff_list *aff_list::get() const {
+  return ptr;
+}
+
+__isl_give isl_aff_list *aff_list::release() {
+  isl_aff_list *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool aff_list::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::checked::ctx aff_list::ctx() const {
+  return isl::checked::ctx(isl_aff_list_get_ctx(ptr));
+}
+
+isl::checked::aff_list aff_list::add(isl::checked::aff el) const
+{
+  auto res = isl_aff_list_add(copy(), el.release());
+  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());
+  return manage(res);
+}
+
+isl::checked::aff_list aff_list::concat(isl::checked::aff_list list2) const
+{
+  auto res = isl_aff_list_concat(copy(), list2.release());
+  return manage(res);
+}
+
+isl::checked::aff_list aff_list::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl_aff_list_drop(copy(), first, n);
+  return manage(res);
+}
+
+stat aff_list::foreach(const std::function<stat(isl::checked::aff)> &fn) const
+{
+  struct fn_data {
+    std::function<stat(isl::checked::aff)> func;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_aff *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_aff_list_foreach(get(), fn_lambda, &fn_data);
+  return manage(res);
+}
+
+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());
+  return manage(res);
+}
+
+class size aff_list::size() const
+{
+  auto res = isl_aff_list_size(get());
+  return manage(res);
+}
+
+inline std::ostream &operator<<(std::ostream &os, const aff_list &obj)
+{
+  char *str = isl_aff_list_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_build
+ast_build manage(__isl_take isl_ast_build *ptr) {
+  return ast_build(ptr);
+}
+ast_build manage_copy(__isl_keep isl_ast_build *ptr) {
+  ptr = isl_ast_build_copy(ptr);
+  return ast_build(ptr);
+}
+
+ast_build::ast_build()
+    : ptr(nullptr) {}
+
+ast_build::ast_build(const ast_build &obj)
+    : ptr(nullptr)
+{
+  ptr = obj.copy();
+  copy_callbacks(obj);
+}
+
+ast_build::ast_build(__isl_take isl_ast_build *ptr)
+    : ptr(ptr) {}
+
+ast_build::ast_build(isl::checked::ctx ctx)
+{
+  auto res = isl_ast_build_alloc(ctx.release());
+  ptr = res;
+}
+
+ast_build &ast_build::operator=(ast_build obj) {
+  std::swap(this->ptr, obj.ptr);
+  copy_callbacks(obj);
+  return *this;
+}
+
+ast_build::~ast_build() {
+  if (ptr)
+    isl_ast_build_free(ptr);
+}
+
+__isl_give isl_ast_build *ast_build::copy() const & {
+  return isl_ast_build_copy(ptr);
+}
+
+__isl_keep isl_ast_build *ast_build::get() const {
+  return ptr;
+}
+
+__isl_give isl_ast_build *ast_build::release() {
+  if (at_each_domain_data)
+    isl_die(ctx().get(), isl_error_invalid, "cannot release object with persistent callbacks", return nullptr);
+  isl_ast_build *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool ast_build::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::checked::ctx ast_build::ctx() const {
+  return isl::checked::ctx(isl_ast_build_get_ctx(ptr));
+}
+
+ast_build &ast_build::copy_callbacks(const ast_build &obj)
+{
+  at_each_domain_data = obj.at_each_domain_data;
+  return *this;
+}
+
+isl_ast_node *ast_build::at_each_domain(isl_ast_node *arg_0, isl_ast_build *arg_1, void *arg_2)
+{
+  auto *data = static_cast<struct at_each_domain_data *>(arg_2);
+  auto ret = (data->func)(manage(arg_0), manage_copy(arg_1));
+  return ret.release();
+}
+
+void ast_build::set_at_each_domain_data(const std::function<isl::checked::ast_node(isl::checked::ast_node, isl::checked::ast_build)> &fn)
+{
+  at_each_domain_data = std::make_shared<struct at_each_domain_data>();
+  at_each_domain_data->func = fn;
+  ptr = isl_ast_build_set_at_each_domain(ptr, &at_each_domain, at_each_domain_data.get());
+}
+
+isl::checked::ast_build ast_build::set_at_each_domain(const std::function<isl::checked::ast_node(isl::checked::ast_node, isl::checked::ast_build)> &fn) const
+{
+  auto copy = *this;
+  copy.set_at_each_domain_data(fn);
+  return copy;
+}
+
+isl::checked::ast_expr ast_build::access_from(isl::checked::multi_pw_aff mpa) const
+{
+  auto res = isl_ast_build_access_from_multi_pw_aff(get(), mpa.release());
+  return manage(res);
+}
+
+isl::checked::ast_expr ast_build::access_from(isl::checked::pw_multi_aff pma) const
+{
+  auto res = isl_ast_build_access_from_pw_multi_aff(get(), pma.release());
+  return manage(res);
+}
+
+isl::checked::ast_expr ast_build::call_from(isl::checked::multi_pw_aff mpa) const
+{
+  auto res = isl_ast_build_call_from_multi_pw_aff(get(), mpa.release());
+  return manage(res);
+}
+
+isl::checked::ast_expr ast_build::call_from(isl::checked::pw_multi_aff pma) const
+{
+  auto res = isl_ast_build_call_from_pw_multi_aff(get(), pma.release());
+  return manage(res);
+}
+
+isl::checked::ast_expr ast_build::expr_from(isl::checked::pw_aff pa) const
+{
+  auto res = isl_ast_build_expr_from_pw_aff(get(), pa.release());
+  return manage(res);
+}
+
+isl::checked::ast_expr ast_build::expr_from(isl::checked::set set) const
+{
+  auto res = isl_ast_build_expr_from_set(get(), set.release());
+  return manage(res);
+}
+
+isl::checked::ast_build ast_build::from_context(isl::checked::set set)
+{
+  auto res = isl_ast_build_from_context(set.release());
+  return manage(res);
+}
+
+isl::checked::ast_node ast_build::node_from(isl::checked::schedule schedule) const
+{
+  auto res = isl_ast_build_node_from_schedule(get(), schedule.release());
+  return manage(res);
+}
+
+isl::checked::ast_node ast_build::node_from_schedule_map(isl::checked::union_map schedule) const
+{
+  auto res = isl_ast_build_node_from_schedule_map(get(), schedule.release());
+  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);
+}
+ast_expr manage_copy(__isl_keep isl_ast_expr *ptr) {
+  ptr = isl_ast_expr_copy(ptr);
+  return ast_expr(ptr);
+}
+
+ast_expr::ast_expr()
+    : ptr(nullptr) {}
+
+ast_expr::ast_expr(const ast_expr &obj)
+    : ptr(nullptr)
+{
+  ptr = obj.copy();
+}
+
+ast_expr::ast_expr(__isl_take isl_ast_expr *ptr)
+    : ptr(ptr) {}
+
+ast_expr &ast_expr::operator=(ast_expr obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+ast_expr::~ast_expr() {
+  if (ptr)
+    isl_ast_expr_free(ptr);
+}
+
+__isl_give isl_ast_expr *ast_expr::copy() const & {
+  return isl_ast_expr_copy(ptr);
+}
+
+__isl_keep isl_ast_expr *ast_expr::get() const {
+  return ptr;
+}
+
+__isl_give isl_ast_expr *ast_expr::release() {
+  isl_ast_expr *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool ast_expr::is_null() const {
+  return ptr == nullptr;
+}
+
+template <typename T, typename>
+boolean ast_expr::isa_type(T subtype) const
+{
+  if (is_null())
+    return boolean();
+  return isl_ast_expr_get_type(get()) == subtype;
+}
+template <class T>
+boolean ast_expr::isa() const
+{
+  return isa_type<decltype(T::type)>(T::type);
+}
+template <class T>
+T ast_expr::as() const
+{
+ if (isa<T>().is_false())
+    isl_die(ctx().get(), isl_error_invalid, "not an object of the requested subtype", return T());
+  return T(copy());
+}
+
+isl::checked::ctx ast_expr::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+std::string ast_expr::to_C_str() const
+{
+  auto res = isl_ast_expr_to_C_str(get());
+  std::string tmp(res);
+  free(res);
+  return tmp;
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_id
+ast_expr_id::ast_expr_id()
+    : ast_expr() {}
+
+ast_expr_id::ast_expr_id(const ast_expr_id &obj)
+    : ast_expr(obj)
+{
+}
+
+ast_expr_id::ast_expr_id(__isl_take isl_ast_expr *ptr)
+    : ast_expr(ptr) {}
+
+ast_expr_id &ast_expr_id::operator=(ast_expr_id obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_id::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+isl::checked::id ast_expr_id::id() const
+{
+  auto res = isl_ast_expr_id_get_id(get());
+  return manage(res);
+}
+
+isl::checked::id ast_expr_id::get_id() const
+{
+  return id();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_id &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_int
+ast_expr_int::ast_expr_int()
+    : ast_expr() {}
+
+ast_expr_int::ast_expr_int(const ast_expr_int &obj)
+    : ast_expr(obj)
+{
+}
+
+ast_expr_int::ast_expr_int(__isl_take isl_ast_expr *ptr)
+    : ast_expr(ptr) {}
+
+ast_expr_int &ast_expr_int::operator=(ast_expr_int obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_int::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+isl::checked::val ast_expr_int::val() const
+{
+  auto res = isl_ast_expr_int_get_val(get());
+  return manage(res);
+}
+
+isl::checked::val ast_expr_int::get_val() const
+{
+  return val();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_int &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op
+ast_expr_op::ast_expr_op()
+    : ast_expr() {}
+
+ast_expr_op::ast_expr_op(const ast_expr_op &obj)
+    : ast_expr(obj)
+{
+}
+
+ast_expr_op::ast_expr_op(__isl_take isl_ast_expr *ptr)
+    : ast_expr(ptr) {}
+
+ast_expr_op &ast_expr_op::operator=(ast_expr_op obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+template <typename T, typename>
+boolean ast_expr_op::isa_type(T subtype) const
+{
+  if (is_null())
+    return boolean();
+  return isl_ast_expr_op_get_type(get()) == subtype;
+}
+template <class T>
+boolean ast_expr_op::isa() const
+{
+  return isa_type<decltype(T::type)>(T::type);
+}
+template <class T>
+T ast_expr_op::as() const
+{
+ if (isa<T>().is_false())
+    isl_die(ctx().get(), isl_error_invalid, "not an object of the requested subtype", return T());
+  return T(copy());
+}
+
+isl::checked::ctx ast_expr_op::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+isl::checked::ast_expr ast_expr_op::arg(int pos) const
+{
+  auto res = isl_ast_expr_op_get_arg(get(), pos);
+  return manage(res);
+}
+
+isl::checked::ast_expr ast_expr_op::get_arg(int pos) const
+{
+  return arg(pos);
+}
+
+class size ast_expr_op::n_arg() const
+{
+  auto res = isl_ast_expr_op_get_n_arg(get());
+  return manage(res);
+}
+
+class size ast_expr_op::get_n_arg() const
+{
+  return n_arg();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_access
+ast_expr_op_access::ast_expr_op_access()
+    : ast_expr_op() {}
+
+ast_expr_op_access::ast_expr_op_access(const ast_expr_op_access &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_access::ast_expr_op_access(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_access &ast_expr_op_access::operator=(ast_expr_op_access obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_access::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_access &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_add
+ast_expr_op_add::ast_expr_op_add()
+    : ast_expr_op() {}
+
+ast_expr_op_add::ast_expr_op_add(const ast_expr_op_add &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_add::ast_expr_op_add(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_add &ast_expr_op_add::operator=(ast_expr_op_add obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_add::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_add &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_address_of
+ast_expr_op_address_of::ast_expr_op_address_of()
+    : ast_expr_op() {}
+
+ast_expr_op_address_of::ast_expr_op_address_of(const ast_expr_op_address_of &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_address_of::ast_expr_op_address_of(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_address_of &ast_expr_op_address_of::operator=(ast_expr_op_address_of obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_address_of::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_address_of &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_and
+ast_expr_op_and::ast_expr_op_and()
+    : ast_expr_op() {}
+
+ast_expr_op_and::ast_expr_op_and(const ast_expr_op_and &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_and::ast_expr_op_and(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_and &ast_expr_op_and::operator=(ast_expr_op_and obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_and::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_and &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_and_then
+ast_expr_op_and_then::ast_expr_op_and_then()
+    : ast_expr_op() {}
+
+ast_expr_op_and_then::ast_expr_op_and_then(const ast_expr_op_and_then &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_and_then::ast_expr_op_and_then(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_and_then &ast_expr_op_and_then::operator=(ast_expr_op_and_then obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_and_then::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_and_then &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_call
+ast_expr_op_call::ast_expr_op_call()
+    : ast_expr_op() {}
+
+ast_expr_op_call::ast_expr_op_call(const ast_expr_op_call &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_call::ast_expr_op_call(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_call &ast_expr_op_call::operator=(ast_expr_op_call obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_call::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_call &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_cond
+ast_expr_op_cond::ast_expr_op_cond()
+    : ast_expr_op() {}
+
+ast_expr_op_cond::ast_expr_op_cond(const ast_expr_op_cond &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_cond::ast_expr_op_cond(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_cond &ast_expr_op_cond::operator=(ast_expr_op_cond obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_cond::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_cond &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_div
+ast_expr_op_div::ast_expr_op_div()
+    : ast_expr_op() {}
+
+ast_expr_op_div::ast_expr_op_div(const ast_expr_op_div &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_div::ast_expr_op_div(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_div &ast_expr_op_div::operator=(ast_expr_op_div obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_div::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_div &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_eq
+ast_expr_op_eq::ast_expr_op_eq()
+    : ast_expr_op() {}
+
+ast_expr_op_eq::ast_expr_op_eq(const ast_expr_op_eq &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_eq::ast_expr_op_eq(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_eq &ast_expr_op_eq::operator=(ast_expr_op_eq obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_eq::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_eq &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_fdiv_q
+ast_expr_op_fdiv_q::ast_expr_op_fdiv_q()
+    : ast_expr_op() {}
+
+ast_expr_op_fdiv_q::ast_expr_op_fdiv_q(const ast_expr_op_fdiv_q &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_fdiv_q::ast_expr_op_fdiv_q(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_fdiv_q &ast_expr_op_fdiv_q::operator=(ast_expr_op_fdiv_q obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_fdiv_q::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_fdiv_q &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_ge
+ast_expr_op_ge::ast_expr_op_ge()
+    : ast_expr_op() {}
+
+ast_expr_op_ge::ast_expr_op_ge(const ast_expr_op_ge &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_ge::ast_expr_op_ge(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_ge &ast_expr_op_ge::operator=(ast_expr_op_ge obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_ge::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_ge &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_gt
+ast_expr_op_gt::ast_expr_op_gt()
+    : ast_expr_op() {}
+
+ast_expr_op_gt::ast_expr_op_gt(const ast_expr_op_gt &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_gt::ast_expr_op_gt(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_gt &ast_expr_op_gt::operator=(ast_expr_op_gt obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_gt::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_gt &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_le
+ast_expr_op_le::ast_expr_op_le()
+    : ast_expr_op() {}
+
+ast_expr_op_le::ast_expr_op_le(const ast_expr_op_le &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_le::ast_expr_op_le(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_le &ast_expr_op_le::operator=(ast_expr_op_le obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_le::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_le &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_lt
+ast_expr_op_lt::ast_expr_op_lt()
+    : ast_expr_op() {}
+
+ast_expr_op_lt::ast_expr_op_lt(const ast_expr_op_lt &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_lt::ast_expr_op_lt(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_lt &ast_expr_op_lt::operator=(ast_expr_op_lt obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_lt::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_lt &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_max
+ast_expr_op_max::ast_expr_op_max()
+    : ast_expr_op() {}
+
+ast_expr_op_max::ast_expr_op_max(const ast_expr_op_max &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_max::ast_expr_op_max(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_max &ast_expr_op_max::operator=(ast_expr_op_max obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_max::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_max &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_member
+ast_expr_op_member::ast_expr_op_member()
+    : ast_expr_op() {}
+
+ast_expr_op_member::ast_expr_op_member(const ast_expr_op_member &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_member::ast_expr_op_member(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_member &ast_expr_op_member::operator=(ast_expr_op_member obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_member::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_member &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_min
+ast_expr_op_min::ast_expr_op_min()
+    : ast_expr_op() {}
+
+ast_expr_op_min::ast_expr_op_min(const ast_expr_op_min &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_min::ast_expr_op_min(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_min &ast_expr_op_min::operator=(ast_expr_op_min obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_min::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_min &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_minus
+ast_expr_op_minus::ast_expr_op_minus()
+    : ast_expr_op() {}
+
+ast_expr_op_minus::ast_expr_op_minus(const ast_expr_op_minus &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_minus::ast_expr_op_minus(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_minus &ast_expr_op_minus::operator=(ast_expr_op_minus obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_minus::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_minus &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_mul
+ast_expr_op_mul::ast_expr_op_mul()
+    : ast_expr_op() {}
+
+ast_expr_op_mul::ast_expr_op_mul(const ast_expr_op_mul &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_mul::ast_expr_op_mul(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_mul &ast_expr_op_mul::operator=(ast_expr_op_mul obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_mul::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_mul &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_or
+ast_expr_op_or::ast_expr_op_or()
+    : ast_expr_op() {}
+
+ast_expr_op_or::ast_expr_op_or(const ast_expr_op_or &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_or::ast_expr_op_or(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_or &ast_expr_op_or::operator=(ast_expr_op_or obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_or::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_or &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_or_else
+ast_expr_op_or_else::ast_expr_op_or_else()
+    : ast_expr_op() {}
+
+ast_expr_op_or_else::ast_expr_op_or_else(const ast_expr_op_or_else &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_or_else::ast_expr_op_or_else(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_or_else &ast_expr_op_or_else::operator=(ast_expr_op_or_else obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_or_else::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_or_else &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_pdiv_q
+ast_expr_op_pdiv_q::ast_expr_op_pdiv_q()
+    : ast_expr_op() {}
+
+ast_expr_op_pdiv_q::ast_expr_op_pdiv_q(const ast_expr_op_pdiv_q &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_pdiv_q::ast_expr_op_pdiv_q(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_pdiv_q &ast_expr_op_pdiv_q::operator=(ast_expr_op_pdiv_q obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_pdiv_q::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_pdiv_q &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_pdiv_r
+ast_expr_op_pdiv_r::ast_expr_op_pdiv_r()
+    : ast_expr_op() {}
+
+ast_expr_op_pdiv_r::ast_expr_op_pdiv_r(const ast_expr_op_pdiv_r &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_pdiv_r::ast_expr_op_pdiv_r(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_pdiv_r &ast_expr_op_pdiv_r::operator=(ast_expr_op_pdiv_r obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_pdiv_r::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_pdiv_r &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_select
+ast_expr_op_select::ast_expr_op_select()
+    : ast_expr_op() {}
+
+ast_expr_op_select::ast_expr_op_select(const ast_expr_op_select &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_select::ast_expr_op_select(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_select &ast_expr_op_select::operator=(ast_expr_op_select obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_select::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_select &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_sub
+ast_expr_op_sub::ast_expr_op_sub()
+    : ast_expr_op() {}
+
+ast_expr_op_sub::ast_expr_op_sub(const ast_expr_op_sub &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_sub::ast_expr_op_sub(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_sub &ast_expr_op_sub::operator=(ast_expr_op_sub obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_sub::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_sub &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_zdiv_r
+ast_expr_op_zdiv_r::ast_expr_op_zdiv_r()
+    : ast_expr_op() {}
+
+ast_expr_op_zdiv_r::ast_expr_op_zdiv_r(const ast_expr_op_zdiv_r &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_zdiv_r::ast_expr_op_zdiv_r(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_zdiv_r &ast_expr_op_zdiv_r::operator=(ast_expr_op_zdiv_r obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_expr_op_zdiv_r::ctx() const {
+  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_zdiv_r &obj)
+{
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_node
+ast_node manage(__isl_take isl_ast_node *ptr) {
+  return ast_node(ptr);
+}
+ast_node manage_copy(__isl_keep isl_ast_node *ptr) {
+  ptr = isl_ast_node_copy(ptr);
+  return ast_node(ptr);
+}
+
+ast_node::ast_node()
+    : ptr(nullptr) {}
+
+ast_node::ast_node(const ast_node &obj)
+    : ptr(nullptr)
+{
+  ptr = obj.copy();
+}
+
+ast_node::ast_node(__isl_take isl_ast_node *ptr)
+    : ptr(ptr) {}
+
+ast_node &ast_node::operator=(ast_node obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+ast_node::~ast_node() {
+  if (ptr)
+    isl_ast_node_free(ptr);
+}
+
+__isl_give isl_ast_node *ast_node::copy() const & {
+  return isl_ast_node_copy(ptr);
+}
+
+__isl_keep isl_ast_node *ast_node::get() const {
+  return ptr;
+}
+
+__isl_give isl_ast_node *ast_node::release() {
+  isl_ast_node *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool ast_node::is_null() const {
+  return ptr == nullptr;
+}
+
+template <typename T, typename>
+boolean ast_node::isa_type(T subtype) const
+{
+  if (is_null())
+    return boolean();
+  return isl_ast_node_get_type(get()) == subtype;
+}
+template <class T>
+boolean ast_node::isa() const
+{
+  return isa_type<decltype(T::type)>(T::type);
+}
+template <class T>
+T ast_node::as() const
+{
+ if (isa<T>().is_false())
+    isl_die(ctx().get(), isl_error_invalid, "not an object of the requested subtype", return T());
+  return T(copy());
+}
+
+isl::checked::ctx ast_node::ctx() const {
+  return isl::checked::ctx(isl_ast_node_get_ctx(ptr));
+}
+
+std::string ast_node::to_C_str() const
+{
+  auto res = isl_ast_node_to_C_str(get());
+  std::string tmp(res);
+  free(res);
+  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());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_node_block
+ast_node_block::ast_node_block()
+    : ast_node() {}
+
+ast_node_block::ast_node_block(const ast_node_block &obj)
+    : ast_node(obj)
+{
+}
+
+ast_node_block::ast_node_block(__isl_take isl_ast_node *ptr)
+    : ast_node(ptr) {}
+
+ast_node_block &ast_node_block::operator=(ast_node_block obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_node_block::ctx() const {
+  return isl::checked::ctx(isl_ast_node_get_ctx(ptr));
+}
+
+isl::checked::ast_node_list ast_node_block::children() const
+{
+  auto res = isl_ast_node_block_get_children(get());
+  return manage(res);
+}
+
+isl::checked::ast_node_list ast_node_block::get_children() const
+{
+  return children();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_node_block &obj)
+{
+  char *str = isl_ast_node_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_node_for
+ast_node_for::ast_node_for()
+    : ast_node() {}
+
+ast_node_for::ast_node_for(const ast_node_for &obj)
+    : ast_node(obj)
+{
+}
+
+ast_node_for::ast_node_for(__isl_take isl_ast_node *ptr)
+    : ast_node(ptr) {}
+
+ast_node_for &ast_node_for::operator=(ast_node_for obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_node_for::ctx() const {
+  return isl::checked::ctx(isl_ast_node_get_ctx(ptr));
+}
+
+isl::checked::ast_node ast_node_for::body() const
+{
+  auto res = isl_ast_node_for_get_body(get());
+  return manage(res);
+}
+
+isl::checked::ast_node ast_node_for::get_body() const
+{
+  return body();
+}
+
+isl::checked::ast_expr ast_node_for::cond() const
+{
+  auto res = isl_ast_node_for_get_cond(get());
+  return manage(res);
+}
+
+isl::checked::ast_expr ast_node_for::get_cond() const
+{
+  return cond();
+}
+
+isl::checked::ast_expr ast_node_for::inc() const
+{
+  auto res = isl_ast_node_for_get_inc(get());
+  return manage(res);
+}
+
+isl::checked::ast_expr ast_node_for::get_inc() const
+{
+  return inc();
+}
+
+isl::checked::ast_expr ast_node_for::init() const
+{
+  auto res = isl_ast_node_for_get_init(get());
+  return manage(res);
+}
+
+isl::checked::ast_expr ast_node_for::get_init() const
+{
+  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());
+  return manage(res);
+}
+
+isl::checked::ast_expr ast_node_for::get_iterator() const
+{
+  return iterator();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_node_for &obj)
+{
+  char *str = isl_ast_node_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_node_if
+ast_node_if::ast_node_if()
+    : ast_node() {}
+
+ast_node_if::ast_node_if(const ast_node_if &obj)
+    : ast_node(obj)
+{
+}
+
+ast_node_if::ast_node_if(__isl_take isl_ast_node *ptr)
+    : ast_node(ptr) {}
+
+ast_node_if &ast_node_if::operator=(ast_node_if obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_node_if::ctx() const {
+  return isl::checked::ctx(isl_ast_node_get_ctx(ptr));
+}
+
+isl::checked::ast_expr ast_node_if::cond() const
+{
+  auto res = isl_ast_node_if_get_cond(get());
+  return manage(res);
+}
+
+isl::checked::ast_expr ast_node_if::get_cond() const
+{
+  return cond();
+}
+
+isl::checked::ast_node ast_node_if::else_node() const
+{
+  auto res = isl_ast_node_if_get_else_node(get());
+  return manage(res);
+}
+
+isl::checked::ast_node ast_node_if::get_else_node() const
+{
+  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());
+  return manage(res);
+}
+
+isl::checked::ast_node ast_node_if::get_then_node() const
+{
+  return then_node();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_node_if &obj)
+{
+  char *str = isl_ast_node_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_node_list
+ast_node_list manage(__isl_take isl_ast_node_list *ptr) {
+  return ast_node_list(ptr);
+}
+ast_node_list manage_copy(__isl_keep isl_ast_node_list *ptr) {
+  ptr = isl_ast_node_list_copy(ptr);
+  return ast_node_list(ptr);
+}
+
+ast_node_list::ast_node_list()
+    : ptr(nullptr) {}
+
+ast_node_list::ast_node_list(const ast_node_list &obj)
+    : ptr(nullptr)
+{
+  ptr = obj.copy();
+}
+
+ast_node_list::ast_node_list(__isl_take isl_ast_node_list *ptr)
+    : ptr(ptr) {}
+
+ast_node_list::ast_node_list(isl::checked::ctx ctx, int n)
+{
+  auto res = isl_ast_node_list_alloc(ctx.release(), n);
+  ptr = res;
+}
+
+ast_node_list::ast_node_list(isl::checked::ast_node el)
+{
+  auto res = isl_ast_node_list_from_ast_node(el.release());
+  ptr = res;
+}
+
+ast_node_list &ast_node_list::operator=(ast_node_list obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+ast_node_list::~ast_node_list() {
+  if (ptr)
+    isl_ast_node_list_free(ptr);
+}
+
+__isl_give isl_ast_node_list *ast_node_list::copy() const & {
+  return isl_ast_node_list_copy(ptr);
+}
+
+__isl_keep isl_ast_node_list *ast_node_list::get() const {
+  return ptr;
+}
+
+__isl_give isl_ast_node_list *ast_node_list::release() {
+  isl_ast_node_list *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool ast_node_list::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::checked::ctx ast_node_list::ctx() const {
+  return isl::checked::ctx(isl_ast_node_list_get_ctx(ptr));
+}
+
+isl::checked::ast_node_list ast_node_list::add(isl::checked::ast_node el) const
+{
+  auto res = isl_ast_node_list_add(copy(), el.release());
+  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());
+  return manage(res);
+}
+
+isl::checked::ast_node_list ast_node_list::concat(isl::checked::ast_node_list list2) const
+{
+  auto res = isl_ast_node_list_concat(copy(), list2.release());
+  return manage(res);
+}
+
+isl::checked::ast_node_list ast_node_list::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl_ast_node_list_drop(copy(), first, n);
+  return manage(res);
+}
+
+stat ast_node_list::foreach(const std::function<stat(isl::checked::ast_node)> &fn) const
+{
+  struct fn_data {
+    std::function<stat(isl::checked::ast_node)> func;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_ast_node *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_ast_node_list_foreach(get(), fn_lambda, &fn_data);
+  return manage(res);
+}
+
+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());
+  return manage(res);
+}
+
+class size ast_node_list::size() const
+{
+  auto res = isl_ast_node_list_size(get());
+  return manage(res);
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_node_list &obj)
+{
+  char *str = isl_ast_node_list_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_node_mark
+ast_node_mark::ast_node_mark()
+    : ast_node() {}
+
+ast_node_mark::ast_node_mark(const ast_node_mark &obj)
+    : ast_node(obj)
+{
+}
+
+ast_node_mark::ast_node_mark(__isl_take isl_ast_node *ptr)
+    : ast_node(ptr) {}
+
+ast_node_mark &ast_node_mark::operator=(ast_node_mark obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_node_mark::ctx() const {
+  return isl::checked::ctx(isl_ast_node_get_ctx(ptr));
+}
+
+isl::checked::id ast_node_mark::id() const
+{
+  auto res = isl_ast_node_mark_get_id(get());
+  return manage(res);
+}
+
+isl::checked::id ast_node_mark::get_id() const
+{
+  return id();
+}
+
+isl::checked::ast_node ast_node_mark::node() const
+{
+  auto res = isl_ast_node_mark_get_node(get());
+  return manage(res);
+}
+
+isl::checked::ast_node ast_node_mark::get_node() const
+{
+  return node();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_node_mark &obj)
+{
+  char *str = isl_ast_node_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_node_user
+ast_node_user::ast_node_user()
+    : ast_node() {}
+
+ast_node_user::ast_node_user(const ast_node_user &obj)
+    : ast_node(obj)
+{
+}
+
+ast_node_user::ast_node_user(__isl_take isl_ast_node *ptr)
+    : ast_node(ptr) {}
+
+ast_node_user &ast_node_user::operator=(ast_node_user obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::checked::ctx ast_node_user::ctx() const {
+  return isl::checked::ctx(isl_ast_node_get_ctx(ptr));
+}
+
+isl::checked::ast_expr ast_node_user::expr() const
+{
+  auto res = isl_ast_node_user_get_expr(get());
+  return manage(res);
+}
+
+isl::checked::ast_expr ast_node_user::get_expr() const
+{
+  return expr();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_node_user &obj)
+{
+  char *str = isl_ast_node_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::basic_map
+basic_map manage(__isl_take isl_basic_map *ptr) {
+  return basic_map(ptr);
+}
+basic_map manage_copy(__isl_keep isl_basic_map *ptr) {
+  ptr = isl_basic_map_copy(ptr);
+  return basic_map(ptr);
+}
+
+basic_map::basic_map()
+    : ptr(nullptr) {}
+
+basic_map::basic_map(const basic_map &obj)
+    : ptr(nullptr)
+{
+  ptr = obj.copy();
+}
+
+basic_map::basic_map(__isl_take isl_basic_map *ptr)
+    : ptr(ptr) {}
+
+basic_map::basic_map(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_basic_map_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
+basic_map &basic_map::operator=(basic_map obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+basic_map::~basic_map() {
+  if (ptr)
+    isl_basic_map_free(ptr);
+}
+
+__isl_give isl_basic_map *basic_map::copy() const & {
+  return isl_basic_map_copy(ptr);
+}
+
+__isl_keep isl_basic_map *basic_map::get() const {
+  return ptr;
+}
+
+__isl_give isl_basic_map *basic_map::release() {
+  isl_basic_map *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool basic_map::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::checked::ctx basic_map::ctx() const {
+  return isl::checked::ctx(isl_basic_map_get_ctx(ptr));
+}
+
+isl::checked::basic_map basic_map::affine_hull() const
+{
+  auto res = isl_basic_map_affine_hull(copy());
+  return manage(res);
+}
+
+isl::checked::basic_map basic_map::apply_domain(isl::checked::basic_map bmap2) const
+{
+  auto res = isl_basic_map_apply_domain(copy(), bmap2.release());
+  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());
+  return manage(res);
+}
+
+isl::checked::basic_map basic_map::detect_equalities() const
+{
+  auto res = isl_basic_map_detect_equalities(copy());
+  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());
+  return manage(res);
+}
+
+isl::checked::basic_map basic_map::flatten_domain() const
+{
+  auto res = isl_basic_map_flatten_domain(copy());
+  return manage(res);
+}
+
+isl::checked::basic_map basic_map::flatten_range() const
+{
+  auto res = isl_basic_map_flatten_range(copy());
+  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());
+  return manage(res);
+}
+
+boolean basic_map::is_equal(const isl::checked::basic_map &bmap2) const
+{
+  auto res = isl_basic_map_is_equal(get(), bmap2.get());
+  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());
+  return manage(res);
+}
+
+isl::checked::basic_map basic_map::sample() const
+{
+  auto res = isl_basic_map_sample(copy());
+  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());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::basic_set
+basic_set manage(__isl_take isl_basic_set *ptr) {
+  return basic_set(ptr);
+}
+basic_set manage_copy(__isl_keep isl_basic_set *ptr) {
+  ptr = isl_basic_set_copy(ptr);
+  return basic_set(ptr);
+}
+
+basic_set::basic_set()
+    : ptr(nullptr) {}
+
+basic_set::basic_set(const basic_set &obj)
+    : ptr(nullptr)
+{
+  ptr = obj.copy();
+}
+
+basic_set::basic_set(__isl_take isl_basic_set *ptr)
+    : ptr(ptr) {}
+
+basic_set::basic_set(isl::checked::point pnt)
+{
+  auto res = isl_basic_set_from_point(pnt.release());
+  ptr = res;
+}
+
+basic_set::basic_set(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_basic_set_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
+basic_set &basic_set::operator=(basic_set obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+basic_set::~basic_set() {
+  if (ptr)
+    isl_basic_set_free(ptr);
+}
+
+__isl_give isl_basic_set *basic_set::copy() const & {
+  return isl_basic_set_copy(ptr);
+}
+
+__isl_keep isl_basic_set *basic_set::get() const {
+  return ptr;
+}
+
+__isl_give isl_basic_set *basic_set::release() {
+  isl_basic_set *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool basic_set::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::checked::ctx basic_set::ctx() const {
+  return isl::checked::ctx(isl_basic_set_get_ctx(ptr));
+}
+
+isl::checked::basic_set basic_set::affine_hull() const
+{
+  auto res = isl_basic_set_affine_hull(copy());
+  return manage(res);
+}
+
+isl::checked::basic_set basic_set::apply(isl::checked::basic_map bmap) const
+{
+  auto res = isl_basic_set_apply(copy(), bmap.release());
+  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());
+  return manage(res);
+}
+
+isl::checked::val basic_set::dim_max_val(int pos) const
+{
+  auto res = isl_basic_set_dim_max_val(copy(), pos);
+  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());
+  return manage(res);
+}
+
+boolean basic_set::is_equal(const isl::checked::basic_set &bset2) const
+{
+  auto res = isl_basic_set_is_equal(get(), bset2.get());
+  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());
+  return manage(res);
+}
+
+isl::checked::point basic_set::sample_point() const
+{
+  auto res = isl_basic_set_sample_point(copy());
+  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());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::fixed_box
+fixed_box manage(__isl_take isl_fixed_box *ptr) {
+  return fixed_box(ptr);
+}
+fixed_box manage_copy(__isl_keep isl_fixed_box *ptr) {
+  ptr = isl_fixed_box_copy(ptr);
+  return fixed_box(ptr);
+}
+
+fixed_box::fixed_box()
+    : ptr(nullptr) {}
+
+fixed_box::fixed_box(const fixed_box &obj)
+    : ptr(nullptr)
+{
+  ptr = obj.copy();
+}
+
+fixed_box::fixed_box(__isl_take isl_fixed_box *ptr)
+    : ptr(ptr) {}
+
+fixed_box &fixed_box::operator=(fixed_box obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+fixed_box::~fixed_box() {
+  if (ptr)
+    isl_fixed_box_free(ptr);
+}
+
+__isl_give isl_fixed_box *fixed_box::copy() const & {
+  return isl_fixed_box_copy(ptr);
+}
+
+__isl_keep isl_fixed_box *fixed_box::get() const {
+  return ptr;
+}
+
+__isl_give isl_fixed_box *fixed_box::release() {
+  isl_fixed_box *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool fixed_box::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::checked::ctx fixed_box::ctx() const {
+  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());
+  return manage(res);
+}
+
+isl::checked::multi_aff fixed_box::get_offset() const
+{
+  return offset();
+}
+
+isl::checked::multi_val fixed_box::size() const
+{
+  auto res = isl_fixed_box_get_size(get());
+  return manage(res);
+}
+
+isl::checked::multi_val fixed_box::get_size() const
+{
+  return size();
+}
+
+isl::checked::space fixed_box::space() const
+{
+  auto res = isl_fixed_box_get_space(get());
+  return manage(res);
+}
+
+isl::checked::space fixed_box::get_space() const
+{
+  return space();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const fixed_box &obj)
+{
+  char *str = isl_fixed_box_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::id
+id manage(__isl_take isl_id *ptr) {
+  return id(ptr);
+}
+id manage_copy(__isl_keep isl_id *ptr) {
+  ptr = isl_id_copy(ptr);
+  return id(ptr);
+}
+
+id::id()
+    : ptr(nullptr) {}
+
+id::id(const id &obj)
+    : ptr(nullptr)
+{
+  ptr = obj.copy();
+}
+
+id::id(__isl_take isl_id *ptr)
+    : ptr(ptr) {}
+
+id::id(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_id_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
+id &id::operator=(id obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+id::~id() {
+  if (ptr)
+    isl_id_free(ptr);
+}
+
+__isl_give isl_id *id::copy() const & {
+  return isl_id_copy(ptr);
+}
+
+__isl_keep isl_id *id::get() const {
+  return ptr;
+}
+
+__isl_give isl_id *id::release() {
+  isl_id *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool id::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::checked::ctx id::ctx() const {
+  return isl::checked::ctx(isl_id_get_ctx(ptr));
+}
+
+std::string id::name() const
+{
+  auto res = isl_id_get_name(get());
+  std::string tmp(res);
+  return tmp;
+}
+
+std::string id::get_name() const
+{
+  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());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::id_list
+id_list manage(__isl_take isl_id_list *ptr) {
+  return id_list(ptr);
+}
+id_list manage_copy(__isl_keep isl_id_list *ptr) {
+  ptr = isl_id_list_copy(ptr);
+  return id_list(ptr);
+}
+
+id_list::id_list()
+    : ptr(nullptr) {}
+
+id_list::id_list(const id_list &obj)
+    : ptr(nullptr)
+{
+  ptr = obj.copy();
+}
+
+id_list::id_list(__isl_take isl_id_list *ptr)
+    : ptr(ptr) {}
+
+id_list::id_list(isl::checked::ctx ctx, int n)
+{
+  auto res = isl_id_list_alloc(ctx.release(), n);
+  ptr = res;
+}
+
+id_list::id_list(isl::checked::id el)
+{
+  auto res = isl_id_list_from_id(el.release());
+  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;
+}
+
+id_list::~id_list() {
+  if (ptr)
+    isl_id_list_free(ptr);
+}
+
+__isl_give isl_id_list *id_list::copy() const & {
+  return isl_id_list_copy(ptr);
+}
+
+__isl_keep isl_id_list *id_list::get() const {
+  return ptr;
+}
+
+__isl_give isl_id_list *id_list::release() {
+  isl_id_list *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool id_list::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::checked::ctx id_list::ctx() const {
+  return isl::checked::ctx(isl_id_list_get_ctx(ptr));
+}
+
+isl::checked::id_list id_list::add(isl::checked::id el) const
+{
+  auto res = isl_id_list_add(copy(), el.release());
+  return manage(res);
+}
+
+isl::checked::id_list id_list::add(const std::string &el) const
+{
+  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());
+  return manage(res);
+}
+
+isl::checked::id_list id_list::concat(isl::checked::id_list list2) const
+{
+  auto res = isl_id_list_concat(copy(), list2.release());
+  return manage(res);
+}
+
+isl::checked::id_list id_list::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl_id_list_drop(copy(), first, n);
+  return manage(res);
+}
+
+stat id_list::foreach(const std::function<stat(isl::checked::id)> &fn) const
+{
+  struct fn_data {
+    std::function<stat(isl::checked::id)> func;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_id *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_id_list_foreach(get(), fn_lambda, &fn_data);
+  return manage(res);
+}
+
+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());
+  return manage(res);
+}
+
+isl::checked::id_list id_list::insert(unsigned int pos, const std::string &el) const
+{
+  return this->insert(pos, isl::checked::id(ctx(), el));
+}
+
+class size id_list::size() const
+{
+  auto res = isl_id_list_size(get());
+  return manage(res);
+}
+
+inline std::ostream &operator<<(std::ostream &os, const id_list &obj)
+{
+  char *str = isl_id_list_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::map
+map manage(__isl_take isl_map *ptr) {
+  return map(ptr);
+}
+map manage_copy(__isl_keep isl_map *ptr) {
+  ptr = isl_map_copy(ptr);
+  return map(ptr);
+}
+
+map::map()
+    : ptr(nullptr) {}
+
+map::map(const map &obj)
+    : ptr(nullptr)
+{
+  ptr = obj.copy();
+}
+
+map::map(__isl_take isl_map *ptr)
+    : ptr(ptr) {}
+
+map::map(isl::checked::basic_map bmap)
+{
+  auto res = isl_map_from_basic_map(bmap.release());
+  ptr = res;
+}
+
+map::map(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_map_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
+map &map::operator=(map obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+map::~map() {
+  if (ptr)
+    isl_map_free(ptr);
+}
+
+__isl_give isl_map *map::copy() const & {
+  return isl_map_copy(ptr);
+}
+
+__isl_keep isl_map *map::get() const {
+  return ptr;
+}
+
+__isl_give isl_map *map::release() {
+  isl_map *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool map::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::checked::ctx map::ctx() const {
+  return isl::checked::ctx(isl_map_get_ctx(ptr));
+}
+
+isl::checked::basic_map map::affine_hull() const
+{
+  auto res = isl_map_affine_hull(copy());
+  return manage(res);
+}
+
+isl::checked::map map::apply_domain(isl::checked::map map2) const
+{
+  auto res = isl_map_apply_domain(copy(), map2.release());
+  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());
+  return manage(res);
+}
+
+isl::checked::set map::bind_range(isl::checked::multi_id tuple) const
+{
+  auto res = isl_map_bind_range(copy(), tuple.release());
+  return manage(res);
+}
+
+isl::checked::map map::coalesce() const
+{
+  auto res = isl_map_coalesce(copy());
+  return manage(res);
+}
+
+isl::checked::map map::complement() const
+{
+  auto res = isl_map_complement(copy());
+  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());
+  return manage(res);
+}
+
+isl::checked::set map::deltas() const
+{
+  auto res = isl_map_deltas(copy());
+  return manage(res);
+}
+
+isl::checked::map map::detect_equalities() const
+{
+  auto res = isl_map_detect_equalities(copy());
+  return manage(res);
+}
+
+isl::checked::set map::domain() const
+{
+  auto res = isl_map_domain(copy());
+  return manage(res);
+}
+
+isl::checked::map map::domain_factor_domain() const
+{
+  auto res = isl_map_domain_factor_domain(copy());
+  return manage(res);
+}
+
+isl::checked::map map::domain_factor_range() const
+{
+  auto res = isl_map_domain_factor_range(copy());
+  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());
+  return manage(res);
+}
+
+isl::checked::map map::eq_at(isl::checked::multi_pw_aff mpa) const
+{
+  auto res = isl_map_eq_at_multi_pw_aff(copy(), mpa.release());
+  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());
+  return manage(res);
+}
+
+isl::checked::map map::factor_range() const
+{
+  auto res = isl_map_factor_range(copy());
+  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());
+  return manage(res);
+}
+
+isl::checked::map map::flatten_domain() const
+{
+  auto res = isl_map_flatten_domain(copy());
+  return manage(res);
+}
+
+isl::checked::map map::flatten_range() const
+{
+  auto res = isl_map_flatten_range(copy());
+  return manage(res);
+}
+
+stat map::foreach_basic_map(const std::function<stat(isl::checked::basic_map)> &fn) const
+{
+  struct fn_data {
+    std::function<stat(isl::checked::basic_map)> func;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_basic_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_foreach_basic_map(get(), fn_lambda, &fn_data);
+  return manage(res);
+}
+
+stat map::foreach_map(const std::function<stat(isl::checked::map)> &fn) const
+{
+  return isl::checked::union_map(*this).foreach_map(fn);
+}
+
+isl::checked::map map::gist(isl::checked::map context) const
+{
+  auto res = isl_map_gist(copy(), context.release());
+  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());
+  return manage(res);
+}
+
+isl::checked::map map::intersect_range(isl::checked::set set) const
+{
+  auto res = isl_map_intersect_range(copy(), set.release());
+  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());
+  return manage(res);
+}
+
+boolean map::is_disjoint(const isl::checked::map &map2) const
+{
+  auto res = isl_map_is_disjoint(get(), map2.get());
+  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());
+  return manage(res);
+}
+
+boolean map::is_equal(const isl::checked::map &map2) const
+{
+  auto res = isl_map_is_equal(get(), map2.get());
+  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());
+  return manage(res);
+}
+
+boolean map::is_single_valued() const
+{
+  auto res = isl_map_is_single_valued(get());
+  return manage(res);
+}
+
+boolean map::is_strict_subset(const isl::checked::map &map2) const
+{
+  auto res = isl_map_is_strict_subset(get(), map2.get());
+  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());
+  return manage(res);
+}
+
+isl::checked::map map::lex_gt_at(isl::checked::multi_pw_aff mpa) const
+{
+  auto res = isl_map_lex_gt_at_multi_pw_aff(copy(), mpa.release());
+  return manage(res);
+}
+
+isl::checked::map map::lex_le_at(isl::checked::multi_pw_aff mpa) const
+{
+  auto res = isl_map_lex_le_at_multi_pw_aff(copy(), mpa.release());
+  return manage(res);
+}
+
+isl::checked::map map::lex_lt_at(isl::checked::multi_pw_aff mpa) const
+{
+  auto res = isl_map_lex_lt_at_multi_pw_aff(copy(), mpa.release());
+  return manage(res);
+}
+
+isl::checked::map map::lexmax() const
+{
+  auto res = isl_map_lexmax(copy());
+  return manage(res);
+}
+
+isl::checked::pw_multi_aff map::lexmax_pw_multi_aff() const
+{
+  auto res = isl_map_lexmax_pw_multi_aff(copy());
+  return manage(res);
+}
+
+isl::checked::map map::lexmin() const
+{
+  auto res = isl_map_lexmin(copy());
+  return manage(res);
+}
+
+isl::checked::pw_multi_aff map::lexmin_pw_multi_aff() const
+{
+  auto res = isl_map_lexmin_pw_multi_aff(copy());
+  return manage(res);
+}
+
+isl::checked::map map::lower_bound(isl::checked::multi_pw_aff lower) const
+{
+  auto res = isl_map_lower_bound_multi_pw_aff(copy(), lower.release());
+  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());
+  return manage(res);
+}
+
+isl::checked::multi_pw_aff map::min_multi_pw_aff() const
+{
+  auto res = isl_map_min_multi_pw_aff(copy());
+  return manage(res);
+}
+
+isl::checked::basic_map map::polyhedral_hull() const
+{
+  auto res = isl_map_polyhedral_hull(copy());
+  return manage(res);
+}
+
+isl::checked::map map::preimage_domain(isl::checked::multi_aff ma) const
+{
+  auto res = isl_map_preimage_domain_multi_aff(copy(), ma.release());
+  return manage(res);
+}
+
+isl::checked::map map::preimage_domain(isl::checked::multi_pw_aff mpa) const
+{
+  auto res = isl_map_preimage_domain_multi_pw_aff(copy(), mpa.release());
+  return manage(res);
+}
+
+isl::checked::map map::preimage_domain(isl::checked::pw_multi_aff pma) const
+{
+  auto res = isl_map_preimage_domain_pw_multi_aff(copy(), pma.release());
+  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());
+  return manage(res);
+}
+
+isl::checked::map map::preimage_range(isl::checked::pw_multi_aff pma) const
+{
+  auto res = isl_map_preimage_range_pw_multi_aff(copy(), pma.release());
+  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());
+  return manage(res);
+}
+
+isl::checked::set map::range() const
+{
+  auto res = isl_map_range(copy());
+  return manage(res);
+}
+
+isl::checked::map map::range_factor_domain() const
+{
+  auto res = isl_map_range_factor_domain(copy());
+  return manage(res);
+}
+
+isl::checked::map map::range_factor_range() const
+{
+  auto res = isl_map_range_factor_range(copy());
+  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());
+  return manage(res);
+}
+
+isl::checked::basic_map map::sample() const
+{
+  auto res = isl_map_sample(copy());
+  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());
+  return manage(res);
+}
+
+isl::checked::map map::unite(isl::checked::map map2) const
+{
+  auto res = isl_map_union(copy(), map2.release());
+  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());
+  return manage(res);
+}
+
+isl::checked::basic_map map::unshifted_simple_hull() const
+{
+  auto res = isl_map_unshifted_simple_hull(copy());
+  return manage(res);
+}
+
+isl::checked::map map::upper_bound(isl::checked::multi_pw_aff upper) const
+{
+  auto res = isl_map_upper_bound_multi_pw_aff(copy(), upper.release());
+  return manage(res);
+}
+
+isl::checked::set map::wrap() const
+{
+  auto res = isl_map_wrap(copy());
+  return manage(res);
+}
+
+isl::checked::map map::zip() const
+{
+  auto res = isl_map_zip(copy());
+  return manage(res);
+}
+
+inline std::ostream &operator<<(std::ostream &os, const map &obj)
+{
+  char *str = isl_map_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
     return os;
   }
   os << str;
@@ -4323,96 +9783,141 @@ inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_eq &obj)
   return os;
 }
 
-// implementations for isl::ast_expr_op_fdiv_q
-ast_expr_op_fdiv_q::ast_expr_op_fdiv_q()
-    : ast_expr_op() {}
+// 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;
+}
 
-ast_expr_op_fdiv_q::ast_expr_op_fdiv_q(const ast_expr_op_fdiv_q &obj)
-    : ast_expr_op(obj)
+map_list::map_list(isl::checked::map el)
 {
+  auto res = isl_map_list_from_map(el.release());
+  ptr = res;
 }
 
-ast_expr_op_fdiv_q::ast_expr_op_fdiv_q(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+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;
+}
 
-ast_expr_op_fdiv_q &ast_expr_op_fdiv_q::operator=(ast_expr_op_fdiv_q obj) {
+map_list &map_list::operator=(map_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-isl::checked::ctx ast_expr_op_fdiv_q::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+map_list::~map_list() {
+  if (ptr)
+    isl_map_list_free(ptr);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_fdiv_q &obj)
-{
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+__isl_give isl_map_list *map_list::copy() const & {
+  return isl_map_list_copy(ptr);
 }
 
-// implementations for isl::ast_expr_op_ge
-ast_expr_op_ge::ast_expr_op_ge()
-    : ast_expr_op() {}
+__isl_keep isl_map_list *map_list::get() const {
+  return ptr;
+}
 
-ast_expr_op_ge::ast_expr_op_ge(const ast_expr_op_ge &obj)
-    : ast_expr_op(obj)
-{
+__isl_give isl_map_list *map_list::release() {
+  isl_map_list *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
 }
 
-ast_expr_op_ge::ast_expr_op_ge(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+bool map_list::is_null() const {
+  return ptr == nullptr;
+}
 
-ast_expr_op_ge &ast_expr_op_ge::operator=(ast_expr_op_ge obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::ctx map_list::ctx() const {
+  return isl::checked::ctx(isl_map_list_get_ctx(ptr));
 }
 
-isl::checked::ctx ast_expr_op_ge::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_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);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_ge &obj)
+isl::checked::map map_list::at(int index) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  auto res = isl_map_list_get_at(get(), index);
+  return manage(res);
 }
 
-// implementations for isl::ast_expr_op_gt
-ast_expr_op_gt::ast_expr_op_gt()
-    : ast_expr_op() {}
+isl::checked::map map_list::get_at(int index) const
+{
+  return at(index);
+}
 
-ast_expr_op_gt::ast_expr_op_gt(const ast_expr_op_gt &obj)
-    : ast_expr_op(obj)
+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);
 }
 
-ast_expr_op_gt::ast_expr_op_gt(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+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);
+}
 
-ast_expr_op_gt &ast_expr_op_gt::operator=(ast_expr_op_gt obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_op_gt::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+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);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_gt &obj)
+class size map_list::size() const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
+  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;
@@ -4422,762 +9927,764 @@ inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_gt &obj)
   return os;
 }
 
-// implementations for isl::ast_expr_op_le
-ast_expr_op_le::ast_expr_op_le()
-    : ast_expr_op() {}
+// implementations for isl::multi_aff
+multi_aff manage(__isl_take isl_multi_aff *ptr) {
+  return multi_aff(ptr);
+}
+multi_aff manage_copy(__isl_keep isl_multi_aff *ptr) {
+  ptr = isl_multi_aff_copy(ptr);
+  return multi_aff(ptr);
+}
 
-ast_expr_op_le::ast_expr_op_le(const ast_expr_op_le &obj)
-    : ast_expr_op(obj)
+multi_aff::multi_aff()
+    : ptr(nullptr) {}
+
+multi_aff::multi_aff(const multi_aff &obj)
+    : ptr(nullptr)
 {
+  ptr = obj.copy();
 }
 
-ast_expr_op_le::ast_expr_op_le(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+multi_aff::multi_aff(__isl_take isl_multi_aff *ptr)
+    : ptr(ptr) {}
 
-ast_expr_op_le &ast_expr_op_le::operator=(ast_expr_op_le obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+multi_aff::multi_aff(isl::checked::aff aff)
+{
+  auto res = isl_multi_aff_from_aff(aff.release());
+  ptr = res;
 }
 
-isl::checked::ctx ast_expr_op_le::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+multi_aff::multi_aff(isl::checked::space space, isl::checked::aff_list list)
+{
+  auto res = isl_multi_aff_from_aff_list(space.release(), list.release());
+  ptr = res;
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_le &obj)
+multi_aff::multi_aff(isl::checked::ctx ctx, const std::string &str)
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  auto res = isl_multi_aff_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
 }
 
-// implementations for isl::ast_expr_op_lt
-ast_expr_op_lt::ast_expr_op_lt()
-    : ast_expr_op() {}
+multi_aff &multi_aff::operator=(multi_aff obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
 
-ast_expr_op_lt::ast_expr_op_lt(const ast_expr_op_lt &obj)
-    : ast_expr_op(obj)
-{
+multi_aff::~multi_aff() {
+  if (ptr)
+    isl_multi_aff_free(ptr);
 }
 
-ast_expr_op_lt::ast_expr_op_lt(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+__isl_give isl_multi_aff *multi_aff::copy() const & {
+  return isl_multi_aff_copy(ptr);
+}
 
-ast_expr_op_lt &ast_expr_op_lt::operator=(ast_expr_op_lt obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+__isl_keep isl_multi_aff *multi_aff::get() const {
+  return ptr;
 }
 
-isl::checked::ctx ast_expr_op_lt::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+__isl_give isl_multi_aff *multi_aff::release() {
+  isl_multi_aff *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_lt &obj)
-{
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+bool multi_aff::is_null() const {
+  return ptr == nullptr;
 }
 
-// implementations for isl::ast_expr_op_max
-ast_expr_op_max::ast_expr_op_max()
-    : ast_expr_op() {}
+isl::checked::ctx multi_aff::ctx() const {
+  return isl::checked::ctx(isl_multi_aff_get_ctx(ptr));
+}
 
-ast_expr_op_max::ast_expr_op_max(const ast_expr_op_max &obj)
-    : ast_expr_op(obj)
+isl::checked::multi_aff multi_aff::add(isl::checked::multi_aff multi2) const
 {
+  auto res = isl_multi_aff_add(copy(), multi2.release());
+  return manage(res);
 }
 
-ast_expr_op_max::ast_expr_op_max(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+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);
+}
 
-ast_expr_op_max &ast_expr_op_max::operator=(ast_expr_op_max obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_op_max::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+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);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_max &obj)
+isl::checked::union_pw_multi_aff multi_aff::add(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_multi_aff(*this).add(upma2);
 }
 
-// implementations for isl::ast_expr_op_member
-ast_expr_op_member::ast_expr_op_member()
-    : ast_expr_op() {}
+isl::checked::multi_aff multi_aff::add(const isl::checked::aff &multi2) const
+{
+  return this->add(isl::checked::multi_aff(multi2));
+}
 
-ast_expr_op_member::ast_expr_op_member(const ast_expr_op_member &obj)
-    : ast_expr_op(obj)
+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());
+  return manage(res);
 }
 
-ast_expr_op_member::ast_expr_op_member(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+isl::checked::multi_aff multi_aff::add_constant(isl::checked::val v) const
+{
+  auto res = isl_multi_aff_add_constant_val(copy(), v.release());
+  return manage(res);
+}
 
-ast_expr_op_member &ast_expr_op_member::operator=(ast_expr_op_member obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::multi_aff multi_aff::add_constant(long v) const
+{
+  return this->add_constant(isl::checked::val(ctx(), v));
 }
 
-isl::checked::ctx ast_expr_op_member::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+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);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_member &obj)
+isl::checked::map multi_aff::as_map() const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  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();
 }
 
-// implementations for isl::ast_expr_op_min
-ast_expr_op_min::ast_expr_op_min()
-    : ast_expr_op() {}
+isl::checked::pw_multi_aff multi_aff::as_pw_multi_aff() const
+{
+  return isl::checked::pw_multi_aff(*this).as_pw_multi_aff();
+}
 
-ast_expr_op_min::ast_expr_op_min(const ast_expr_op_min &obj)
-    : ast_expr_op(obj)
+isl::checked::set multi_aff::as_set() const
 {
+  auto res = isl_multi_aff_as_set(copy());
+  return manage(res);
 }
 
-ast_expr_op_min::ast_expr_op_min(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+isl::checked::union_map multi_aff::as_union_map() const
+{
+  return isl::checked::pw_multi_aff(*this).as_union_map();
+}
 
-ast_expr_op_min &ast_expr_op_min::operator=(ast_expr_op_min obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::aff multi_aff::at(int pos) const
+{
+  auto res = isl_multi_aff_get_at(get(), pos);
+  return manage(res);
 }
 
-isl::checked::ctx ast_expr_op_min::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+isl::checked::aff multi_aff::get_at(int pos) const
+{
+  return at(pos);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_min &obj)
+isl::checked::basic_set multi_aff::bind(isl::checked::multi_id tuple) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  auto res = isl_multi_aff_bind(copy(), tuple.release());
+  return manage(res);
 }
 
-// implementations for isl::ast_expr_op_minus
-ast_expr_op_minus::ast_expr_op_minus()
-    : ast_expr_op() {}
+isl::checked::multi_aff multi_aff::bind_domain(isl::checked::multi_id tuple) const
+{
+  auto res = isl_multi_aff_bind_domain(copy(), tuple.release());
+  return manage(res);
+}
 
-ast_expr_op_minus::ast_expr_op_minus(const ast_expr_op_minus &obj)
-    : ast_expr_op(obj)
+isl::checked::multi_aff multi_aff::bind_domain_wrapped_domain(isl::checked::multi_id tuple) const
 {
+  auto res = isl_multi_aff_bind_domain_wrapped_domain(copy(), tuple.release());
+  return manage(res);
 }
 
-ast_expr_op_minus::ast_expr_op_minus(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+isl::checked::pw_multi_aff multi_aff::coalesce() const
+{
+  return isl::checked::pw_multi_aff(*this).coalesce();
+}
 
-ast_expr_op_minus &ast_expr_op_minus::operator=(ast_expr_op_minus obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::multi_val multi_aff::constant_multi_val() const
+{
+  auto res = isl_multi_aff_get_constant_multi_val(get());
+  return manage(res);
 }
 
-isl::checked::ctx ast_expr_op_minus::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+isl::checked::multi_val multi_aff::get_constant_multi_val() const
+{
+  return constant_multi_val();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_minus &obj)
+isl::checked::set multi_aff::domain() const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_multi_aff(*this).domain();
 }
 
-// implementations for isl::ast_expr_op_mul
-ast_expr_op_mul::ast_expr_op_mul()
-    : ast_expr_op() {}
+isl::checked::multi_aff multi_aff::domain_map(isl::checked::space space)
+{
+  auto res = isl_multi_aff_domain_map(space.release());
+  return manage(res);
+}
 
-ast_expr_op_mul::ast_expr_op_mul(const ast_expr_op_mul &obj)
-    : ast_expr_op(obj)
+isl::checked::pw_multi_aff multi_aff::extract_pw_multi_aff(const isl::checked::space &space) const
 {
+  return isl::checked::pw_multi_aff(*this).extract_pw_multi_aff(space);
 }
 
-ast_expr_op_mul::ast_expr_op_mul(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+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);
+}
 
-ast_expr_op_mul &ast_expr_op_mul::operator=(ast_expr_op_mul obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::multi_pw_aff multi_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::ctx ast_expr_op_mul::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+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);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_mul &obj)
+isl::checked::pw_multi_aff multi_aff::flat_range_product(const isl::checked::pw_multi_aff &pma2) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_multi_aff(*this).flat_range_product(pma2);
 }
 
-// implementations for isl::ast_expr_op_or
-ast_expr_op_or::ast_expr_op_or()
-    : ast_expr_op() {}
+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);
+}
 
-ast_expr_op_or::ast_expr_op_or(const ast_expr_op_or &obj)
-    : ast_expr_op(obj)
+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));
 }
 
-ast_expr_op_or::ast_expr_op_or(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+isl::checked::multi_aff multi_aff::floor() const
+{
+  auto res = isl_multi_aff_floor(copy());
+  return manage(res);
+}
 
-ast_expr_op_or &ast_expr_op_or::operator=(ast_expr_op_or obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_op_or::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+isl::checked::multi_aff multi_aff::gist(isl::checked::set context) const
+{
+  auto res = isl_multi_aff_gist(copy(), context.release());
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_or &obj)
+isl::checked::union_pw_multi_aff multi_aff::gist(const isl::checked::union_set &context) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_multi_aff(*this).gist(context);
 }
 
-// implementations for isl::ast_expr_op_or_else
-ast_expr_op_or_else::ast_expr_op_or_else()
-    : ast_expr_op() {}
+isl::checked::multi_aff multi_aff::gist(const isl::checked::basic_set &context) const
+{
+  return this->gist(isl::checked::set(context));
+}
 
-ast_expr_op_or_else::ast_expr_op_or_else(const ast_expr_op_or_else &obj)
-    : ast_expr_op(obj)
+isl::checked::multi_aff multi_aff::gist(const isl::checked::point &context) const
 {
+  return this->gist(isl::checked::set(context));
 }
 
-ast_expr_op_or_else::ast_expr_op_or_else(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+boolean multi_aff::has_range_tuple_id() const
+{
+  auto res = isl_multi_aff_has_range_tuple_id(get());
+  return manage(res);
+}
 
-ast_expr_op_or_else &ast_expr_op_or_else::operator=(ast_expr_op_or_else obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::multi_aff multi_aff::identity() const
+{
+  auto res = isl_multi_aff_identity_multi_aff(copy());
+  return manage(res);
 }
 
-isl::checked::ctx ast_expr_op_or_else::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+isl::checked::multi_aff multi_aff::identity_on_domain(isl::checked::space space)
+{
+  auto res = isl_multi_aff_identity_on_domain_space(space.release());
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_or_else &obj)
+isl::checked::multi_aff multi_aff::insert_domain(isl::checked::space domain) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  auto res = isl_multi_aff_insert_domain(copy(), domain.release());
+  return manage(res);
 }
 
-// implementations for isl::ast_expr_op_pdiv_q
-ast_expr_op_pdiv_q::ast_expr_op_pdiv_q()
-    : ast_expr_op() {}
+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);
+}
 
-ast_expr_op_pdiv_q::ast_expr_op_pdiv_q(const ast_expr_op_pdiv_q &obj)
-    : ast_expr_op(obj)
+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);
 }
 
-ast_expr_op_pdiv_q::ast_expr_op_pdiv_q(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+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);
+}
 
-ast_expr_op_pdiv_q &ast_expr_op_pdiv_q::operator=(ast_expr_op_pdiv_q obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_op_pdiv_q::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+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);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_pdiv_q &obj)
+isl::checked::pw_multi_aff multi_aff::intersect_params(const isl::checked::set &set) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_multi_aff(*this).intersect_params(set);
 }
 
-// implementations for isl::ast_expr_op_pdiv_r
-ast_expr_op_pdiv_r::ast_expr_op_pdiv_r()
-    : ast_expr_op() {}
+boolean multi_aff::involves_locals() const
+{
+  auto res = isl_multi_aff_involves_locals(get());
+  return manage(res);
+}
 
-ast_expr_op_pdiv_r::ast_expr_op_pdiv_r(const ast_expr_op_pdiv_r &obj)
-    : ast_expr_op(obj)
+boolean multi_aff::involves_nan() const
 {
+  auto res = isl_multi_aff_involves_nan(get());
+  return manage(res);
 }
 
-ast_expr_op_pdiv_r::ast_expr_op_pdiv_r(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+boolean multi_aff::involves_param(const isl::checked::id &id) const
+{
+  return isl::checked::pw_multi_aff(*this).involves_param(id);
+}
 
-ast_expr_op_pdiv_r &ast_expr_op_pdiv_r::operator=(ast_expr_op_pdiv_r obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+boolean multi_aff::involves_param(const std::string &id) const
+{
+  return this->involves_param(isl::checked::id(ctx(), id));
 }
 
-isl::checked::ctx ast_expr_op_pdiv_r::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+boolean multi_aff::involves_param(const isl::checked::id_list &list) const
+{
+  return isl::checked::pw_multi_aff(*this).involves_param(list);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_pdiv_r &obj)
+boolean multi_aff::isa_multi_aff() const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_multi_aff(*this).isa_multi_aff();
 }
 
-// implementations for isl::ast_expr_op_select
-ast_expr_op_select::ast_expr_op_select()
-    : ast_expr_op() {}
+boolean multi_aff::isa_pw_multi_aff() const
+{
+  return isl::checked::pw_multi_aff(*this).isa_pw_multi_aff();
+}
 
-ast_expr_op_select::ast_expr_op_select(const ast_expr_op_select &obj)
-    : ast_expr_op(obj)
+isl::checked::aff_list multi_aff::list() const
 {
+  auto res = isl_multi_aff_get_list(get());
+  return manage(res);
 }
 
-ast_expr_op_select::ast_expr_op_select(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+isl::checked::aff_list multi_aff::get_list() const
+{
+  return list();
+}
 
-ast_expr_op_select &ast_expr_op_select::operator=(ast_expr_op_select obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_op_select::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+isl::checked::multi_val multi_aff::max_multi_val() const
+{
+  return isl::checked::pw_multi_aff(*this).max_multi_val();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_select &obj)
+isl::checked::multi_pw_aff multi_aff::min(const isl::checked::multi_pw_aff &multi2) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_multi_aff(*this).min(multi2);
 }
 
-// implementations for isl::ast_expr_op_sub
-ast_expr_op_sub::ast_expr_op_sub()
-    : ast_expr_op() {}
+isl::checked::multi_val multi_aff::min_multi_val() const
+{
+  return isl::checked::pw_multi_aff(*this).min_multi_val();
+}
 
-ast_expr_op_sub::ast_expr_op_sub(const ast_expr_op_sub &obj)
-    : ast_expr_op(obj)
+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);
 }
 
-ast_expr_op_sub::ast_expr_op_sub(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+class size multi_aff::n_piece() const
+{
+  return isl::checked::pw_multi_aff(*this).n_piece();
+}
 
-ast_expr_op_sub &ast_expr_op_sub::operator=(ast_expr_op_sub obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::multi_aff multi_aff::neg() const
+{
+  auto res = isl_multi_aff_neg(copy());
+  return manage(res);
 }
 
-isl::checked::ctx ast_expr_op_sub::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+boolean multi_aff::plain_is_empty() const
+{
+  return isl::checked::pw_multi_aff(*this).plain_is_empty();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_sub &obj)
+boolean multi_aff::plain_is_equal(const isl::checked::multi_aff &multi2) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  auto res = isl_multi_aff_plain_is_equal(get(), multi2.get());
+  return manage(res);
 }
 
-// implementations for isl::ast_expr_op_zdiv_r
-ast_expr_op_zdiv_r::ast_expr_op_zdiv_r()
-    : ast_expr_op() {}
+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);
+}
 
-ast_expr_op_zdiv_r::ast_expr_op_zdiv_r(const ast_expr_op_zdiv_r &obj)
-    : ast_expr_op(obj)
+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);
 }
 
-ast_expr_op_zdiv_r::ast_expr_op_zdiv_r(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+boolean multi_aff::plain_is_equal(const isl::checked::aff &multi2) const
+{
+  return this->plain_is_equal(isl::checked::multi_aff(multi2));
+}
 
-ast_expr_op_zdiv_r &ast_expr_op_zdiv_r::operator=(ast_expr_op_zdiv_r obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_op_zdiv_r::ctx() const {
-  return isl::checked::ctx(isl_ast_expr_get_ctx(ptr));
+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);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_zdiv_r &obj)
+isl::checked::multi_aff multi_aff::product(isl::checked::multi_aff multi2) const
 {
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  auto res = isl_multi_aff_product(copy(), multi2.release());
+  return manage(res);
 }
 
-// implementations for isl::ast_node
-ast_node manage(__isl_take isl_ast_node *ptr) {
-  return ast_node(ptr);
+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);
 }
-ast_node manage_copy(__isl_keep isl_ast_node *ptr) {
-  ptr = isl_ast_node_copy(ptr);
-  return ast_node(ptr);
+
+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);
 }
 
-ast_node::ast_node()
-    : ptr(nullptr) {}
+isl::checked::multi_aff multi_aff::product(const isl::checked::aff &multi2) const
+{
+  return this->product(isl::checked::multi_aff(multi2));
+}
 
-ast_node::ast_node(const ast_node &obj)
-    : ptr(nullptr)
+isl::checked::multi_aff multi_aff::pullback(isl::checked::multi_aff ma2) const
 {
-  ptr = obj.copy();
+  auto res = isl_multi_aff_pullback_multi_aff(copy(), ma2.release());
+  return manage(res);
 }
 
-ast_node::ast_node(__isl_take isl_ast_node *ptr)
-    : ptr(ptr) {}
+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);
+}
 
-ast_node &ast_node::operator=(ast_node obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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);
 }
 
-ast_node::~ast_node() {
-  if (ptr)
-    isl_ast_node_free(ptr);
+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_give isl_ast_node *ast_node::copy() const & {
-  return isl_ast_node_copy(ptr);
+isl::checked::multi_aff multi_aff::pullback(const isl::checked::aff &ma2) const
+{
+  return this->pullback(isl::checked::multi_aff(ma2));
 }
 
-__isl_keep isl_ast_node *ast_node::get() const {
-  return ptr;
+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_give isl_ast_node *ast_node::release() {
-  isl_ast_node *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+isl::checked::pw_multi_aff multi_aff::range_factor_domain() const
+{
+  return isl::checked::pw_multi_aff(*this).range_factor_domain();
 }
 
-bool ast_node::is_null() const {
-  return ptr == nullptr;
+isl::checked::pw_multi_aff multi_aff::range_factor_range() const
+{
+  return isl::checked::pw_multi_aff(*this).range_factor_range();
 }
 
-template <typename T, typename>
-boolean ast_node::isa_type(T subtype) const
+isl::checked::multi_aff multi_aff::range_map(isl::checked::space space)
 {
-  if (is_null())
-    return boolean();
-  return isl_ast_node_get_type(get()) == subtype;
+  auto res = isl_multi_aff_range_map(space.release());
+  return manage(res);
 }
-template <class T>
-boolean ast_node::isa() const
+
+isl::checked::multi_aff multi_aff::range_product(isl::checked::multi_aff multi2) const
 {
-  return isa_type<decltype(T::type)>(T::type);
+  auto res = isl_multi_aff_range_product(copy(), multi2.release());
+  return manage(res);
 }
-template <class T>
-T ast_node::as() const
+
+isl::checked::multi_pw_aff multi_aff::range_product(const isl::checked::multi_pw_aff &multi2) const
 {
- if (isa<T>().is_false())
-    isl_die(ctx().get(), isl_error_invalid, "not an object of the requested subtype", return T());
-  return T(copy());
+  return isl::checked::pw_multi_aff(*this).range_product(multi2);
 }
 
-isl::checked::ctx ast_node::ctx() const {
-  return isl::checked::ctx(isl_ast_node_get_ctx(ptr));
+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);
 }
 
-std::string ast_node::to_C_str() const
+isl::checked::pw_multi_aff multi_aff::range_product(const isl::checked::pw_multi_aff &pma2) const
 {
-  auto res = isl_ast_node_to_C_str(get());
-  std::string tmp(res);
-  free(res);
-  return tmp;
+  return isl::checked::pw_multi_aff(*this).range_product(pma2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_node &obj)
+isl::checked::union_pw_multi_aff multi_aff::range_product(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  char *str = isl_ast_node_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_multi_aff(*this).range_product(upma2);
 }
 
-// implementations for isl::ast_node_block
-ast_node_block::ast_node_block()
-    : ast_node() {}
+isl::checked::multi_aff multi_aff::range_product(const isl::checked::aff &multi2) const
+{
+  return this->range_product(isl::checked::multi_aff(multi2));
+}
 
-ast_node_block::ast_node_block(const ast_node_block &obj)
-    : ast_node(obj)
+isl::checked::id multi_aff::range_tuple_id() const
 {
+  auto res = isl_multi_aff_get_range_tuple_id(get());
+  return manage(res);
 }
 
-ast_node_block::ast_node_block(__isl_take isl_ast_node *ptr)
-    : ast_node(ptr) {}
+isl::checked::id multi_aff::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
 
-ast_node_block &ast_node_block::operator=(ast_node_block obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_node_block::ctx() const {
-  return isl::checked::ctx(isl_ast_node_get_ctx(ptr));
+isl::checked::multi_aff multi_aff::scale(isl::checked::multi_val mv) const
+{
+  auto res = isl_multi_aff_scale_multi_val(copy(), mv.release());
+  return manage(res);
 }
 
-isl::checked::ast_node_list ast_node_block::children() const
+isl::checked::multi_aff multi_aff::scale(isl::checked::val v) const
 {
-  auto res = isl_ast_node_block_get_children(get());
+  auto res = isl_multi_aff_scale_val(copy(), v.release());
   return manage(res);
 }
 
-isl::checked::ast_node_list ast_node_block::get_children() const
+isl::checked::multi_aff multi_aff::scale(long v) const
 {
-  return children();
+  return this->scale(isl::checked::val(ctx(), v));
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_node_block &obj)
+isl::checked::multi_aff multi_aff::scale_down(isl::checked::multi_val mv) const
 {
-  char *str = isl_ast_node_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  auto res = isl_multi_aff_scale_down_multi_val(copy(), mv.release());
+  return manage(res);
 }
 
-// implementations for isl::ast_node_for
-ast_node_for::ast_node_for()
-    : ast_node() {}
+isl::checked::multi_aff multi_aff::scale_down(isl::checked::val v) const
+{
+  auto res = isl_multi_aff_scale_down_val(copy(), v.release());
+  return manage(res);
+}
 
-ast_node_for::ast_node_for(const ast_node_for &obj)
-    : ast_node(obj)
+isl::checked::multi_aff multi_aff::scale_down(long v) const
 {
+  return this->scale_down(isl::checked::val(ctx(), v));
 }
 
-ast_node_for::ast_node_for(__isl_take isl_ast_node *ptr)
-    : ast_node(ptr) {}
+isl::checked::multi_aff multi_aff::set_at(int pos, isl::checked::aff el) const
+{
+  auto res = isl_multi_aff_set_at(copy(), pos, el.release());
+  return manage(res);
+}
 
-ast_node_for &ast_node_for::operator=(ast_node_for obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_node_for::ctx() const {
-  return isl::checked::ctx(isl_ast_node_get_ctx(ptr));
+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::ast_node ast_node_for::body() const
+isl::checked::multi_aff multi_aff::set_range_tuple(isl::checked::id id) const
 {
-  auto res = isl_ast_node_for_get_body(get());
+  auto res = isl_multi_aff_set_range_tuple_id(copy(), id.release());
   return manage(res);
 }
 
-isl::checked::ast_node ast_node_for::get_body() const
+isl::checked::multi_aff multi_aff::set_range_tuple(const std::string &id) const
 {
-  return body();
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
 }
 
-isl::checked::ast_expr ast_node_for::cond() const
+class size multi_aff::size() const
 {
-  auto res = isl_ast_node_for_get_cond(get());
+  auto res = isl_multi_aff_size(get());
   return manage(res);
 }
 
-isl::checked::ast_expr ast_node_for::get_cond() const
+isl::checked::space multi_aff::space() const
 {
-  return cond();
+  auto res = isl_multi_aff_get_space(get());
+  return manage(res);
 }
 
-isl::checked::ast_expr ast_node_for::inc() const
+isl::checked::space multi_aff::get_space() const
 {
-  auto res = isl_ast_node_for_get_inc(get());
+  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::ast_expr ast_node_for::get_inc() const
+isl::checked::multi_pw_aff multi_aff::sub(const isl::checked::multi_pw_aff &multi2) const
 {
-  return inc();
+  return isl::checked::pw_multi_aff(*this).sub(multi2);
 }
 
-isl::checked::ast_expr ast_node_for::init() const
+isl::checked::multi_union_pw_aff multi_aff::sub(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  auto res = isl_ast_node_for_get_init(get());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).sub(multi2);
 }
 
-isl::checked::ast_expr ast_node_for::get_init() const
+isl::checked::pw_multi_aff multi_aff::sub(const isl::checked::pw_multi_aff &pma2) const
 {
-  return init();
+  return isl::checked::pw_multi_aff(*this).sub(pma2);
 }
 
-isl::checked::ast_expr ast_node_for::iterator() const
+isl::checked::union_pw_multi_aff multi_aff::sub(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_ast_node_for_get_iterator(get());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).sub(upma2);
 }
 
-isl::checked::ast_expr ast_node_for::get_iterator() const
+isl::checked::multi_aff multi_aff::sub(const isl::checked::aff &multi2) const
 {
-  return iterator();
+  return this->sub(isl::checked::multi_aff(multi2));
 }
 
-boolean ast_node_for::is_degenerate() const
+isl::checked::pw_multi_aff multi_aff::subtract_domain(const isl::checked::set &set) const
 {
-  auto res = isl_ast_node_for_is_degenerate(get());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).subtract_domain(set);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_node_for &obj)
+isl::checked::union_pw_multi_aff multi_aff::subtract_domain(const isl::checked::space &space) const
 {
-  char *str = isl_ast_node_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_multi_aff(*this).subtract_domain(space);
 }
 
-// implementations for isl::ast_node_if
-ast_node_if::ast_node_if()
-    : ast_node() {}
-
-ast_node_if::ast_node_if(const ast_node_if &obj)
-    : ast_node(obj)
+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);
 }
 
-ast_node_if::ast_node_if(__isl_take isl_ast_node *ptr)
-    : ast_node(ptr) {}
+isl::checked::pw_multi_aff_list multi_aff::to_list() const
+{
+  return isl::checked::pw_multi_aff(*this).to_list();
+}
 
-ast_node_if &ast_node_if::operator=(ast_node_if obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_node_if::ctx() const {
-  return isl::checked::ctx(isl_ast_node_get_ctx(ptr));
+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::ast_expr ast_node_if::cond() const
+isl::checked::pw_multi_aff multi_aff::to_pw_multi_aff() const
 {
-  auto res = isl_ast_node_if_get_cond(get());
+  auto res = isl_multi_aff_to_pw_multi_aff(copy());
   return manage(res);
 }
 
-isl::checked::ast_expr ast_node_if::get_cond() const
+isl::checked::union_pw_multi_aff multi_aff::to_union_pw_multi_aff() const
 {
-  return cond();
+  return isl::checked::pw_multi_aff(*this).to_union_pw_multi_aff();
 }
 
-isl::checked::ast_node ast_node_if::else_node() const
+isl::checked::multi_aff multi_aff::unbind_params_insert_domain(isl::checked::multi_id domain) const
 {
-  auto res = isl_ast_node_if_get_else_node(get());
+  auto res = isl_multi_aff_unbind_params_insert_domain(copy(), domain.release());
   return manage(res);
 }
 
-isl::checked::ast_node ast_node_if::get_else_node() const
+isl::checked::multi_pw_aff multi_aff::union_add(const isl::checked::multi_pw_aff &mpa2) const
 {
-  return else_node();
+  return isl::checked::pw_multi_aff(*this).union_add(mpa2);
 }
 
-isl::checked::ast_node ast_node_if::then_node() const
+isl::checked::multi_union_pw_aff multi_aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const
 {
-  auto res = isl_ast_node_if_get_then_node(get());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).union_add(mupa2);
 }
 
-isl::checked::ast_node ast_node_if::get_then_node() const
+isl::checked::pw_multi_aff multi_aff::union_add(const isl::checked::pw_multi_aff &pma2) const
 {
-  return then_node();
+  return isl::checked::pw_multi_aff(*this).union_add(pma2);
 }
 
-boolean ast_node_if::has_else_node() const
+isl::checked::union_pw_multi_aff multi_aff::union_add(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_ast_node_if_has_else_node(get());
+  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());
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_node_if &obj)
+inline std::ostream &operator<<(std::ostream &os, const multi_aff &obj)
 {
-  char *str = isl_ast_node_to_str(obj.get());
+  char *str = isl_multi_aff_to_str(obj.get());
   if (!str) {
     os.setstate(std::ios_base::badbit);
     return os;
@@ -5187,234 +10694,142 @@ inline std::ostream &operator<<(std::ostream &os, const ast_node_if &obj)
   return os;
 }
 
-// implementations for isl::ast_node_list
-ast_node_list manage(__isl_take isl_ast_node_list *ptr) {
-  return ast_node_list(ptr);
+// implementations for isl::multi_id
+multi_id manage(__isl_take isl_multi_id *ptr) {
+  return multi_id(ptr);
 }
-ast_node_list manage_copy(__isl_keep isl_ast_node_list *ptr) {
-  ptr = isl_ast_node_list_copy(ptr);
-  return ast_node_list(ptr);
+multi_id manage_copy(__isl_keep isl_multi_id *ptr) {
+  ptr = isl_multi_id_copy(ptr);
+  return multi_id(ptr);
 }
 
-ast_node_list::ast_node_list()
+multi_id::multi_id()
     : ptr(nullptr) {}
 
-ast_node_list::ast_node_list(const ast_node_list &obj)
+multi_id::multi_id(const multi_id &obj)
     : ptr(nullptr)
 {
   ptr = obj.copy();
 }
 
-ast_node_list::ast_node_list(__isl_take isl_ast_node_list *ptr)
+multi_id::multi_id(__isl_take isl_multi_id *ptr)
     : ptr(ptr) {}
 
-ast_node_list::ast_node_list(isl::checked::ctx ctx, int n)
+multi_id::multi_id(isl::checked::space space, isl::checked::id_list list)
 {
-  auto res = isl_ast_node_list_alloc(ctx.release(), n);
+  auto res = isl_multi_id_from_id_list(space.release(), list.release());
   ptr = res;
 }
 
-ast_node_list::ast_node_list(isl::checked::ast_node el)
+multi_id::multi_id(isl::checked::ctx ctx, const std::string &str)
 {
-  auto res = isl_ast_node_list_from_ast_node(el.release());
+  auto res = isl_multi_id_read_from_str(ctx.release(), str.c_str());
   ptr = res;
 }
 
-ast_node_list &ast_node_list::operator=(ast_node_list obj) {
+multi_id &multi_id::operator=(multi_id obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-ast_node_list::~ast_node_list() {
+multi_id::~multi_id() {
   if (ptr)
-    isl_ast_node_list_free(ptr);
+    isl_multi_id_free(ptr);
 }
 
-__isl_give isl_ast_node_list *ast_node_list::copy() const & {
-  return isl_ast_node_list_copy(ptr);
+__isl_give isl_multi_id *multi_id::copy() const & {
+  return isl_multi_id_copy(ptr);
 }
 
-__isl_keep isl_ast_node_list *ast_node_list::get() const {
+__isl_keep isl_multi_id *multi_id::get() const {
   return ptr;
 }
 
-__isl_give isl_ast_node_list *ast_node_list::release() {
-  isl_ast_node_list *tmp = ptr;
+__isl_give isl_multi_id *multi_id::release() {
+  isl_multi_id *tmp = ptr;
   ptr = nullptr;
   return tmp;
 }
 
-bool ast_node_list::is_null() const {
+bool multi_id::is_null() const {
   return ptr == nullptr;
 }
 
-isl::checked::ctx ast_node_list::ctx() const {
-  return isl::checked::ctx(isl_ast_node_list_get_ctx(ptr));
-}
-
-isl::checked::ast_node_list ast_node_list::add(isl::checked::ast_node el) const
-{
-  auto res = isl_ast_node_list_add(copy(), el.release());
-  return manage(res);
-}
-
-isl::checked::ast_node_list ast_node_list::clear() const
-{
-  auto res = isl_ast_node_list_clear(copy());
-  return manage(res);
+isl::checked::ctx multi_id::ctx() const {
+  return isl::checked::ctx(isl_multi_id_get_ctx(ptr));
 }
 
-isl::checked::ast_node_list ast_node_list::concat(isl::checked::ast_node_list list2) const
+isl::checked::id multi_id::at(int pos) const
 {
-  auto res = isl_ast_node_list_concat(copy(), list2.release());
+  auto res = isl_multi_id_get_at(get(), pos);
   return manage(res);
 }
 
-isl::checked::ast_node_list ast_node_list::drop(unsigned int first, unsigned int n) const
+isl::checked::id multi_id::get_at(int pos) const
 {
-  auto res = isl_ast_node_list_drop(copy(), first, n);
-  return manage(res);
+  return at(pos);
 }
 
-stat ast_node_list::foreach(const std::function<stat(isl::checked::ast_node)> &fn) const
+isl::checked::multi_id multi_id::flat_range_product(isl::checked::multi_id multi2) const
 {
-  struct fn_data {
-    std::function<stat(isl::checked::ast_node)> func;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_ast_node *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_ast_node_list_foreach(get(), fn_lambda, &fn_data);
+  auto res = isl_multi_id_flat_range_product(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::ast_node ast_node_list::at(int index) const
+isl::checked::id_list multi_id::list() const
 {
-  auto res = isl_ast_node_list_get_at(get(), index);
+  auto res = isl_multi_id_get_list(get());
   return manage(res);
 }
 
-isl::checked::ast_node ast_node_list::get_at(int index) const
+isl::checked::id_list multi_id::get_list() const
 {
-  return at(index);
+  return list();
 }
 
-isl::checked::ast_node_list ast_node_list::insert(unsigned int pos, isl::checked::ast_node el) const
+boolean multi_id::plain_is_equal(const isl::checked::multi_id &multi2) const
 {
-  auto res = isl_ast_node_list_insert(copy(), pos, el.release());
+  auto res = isl_multi_id_plain_is_equal(get(), multi2.get());
   return manage(res);
 }
 
-class size ast_node_list::size() const
+isl::checked::multi_id multi_id::range_product(isl::checked::multi_id multi2) const
 {
-  auto res = isl_ast_node_list_size(get());
+  auto res = isl_multi_id_range_product(copy(), multi2.release());
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_node_list &obj)
-{
-  char *str = isl_ast_node_list_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
-}
-
-// implementations for isl::ast_node_mark
-ast_node_mark::ast_node_mark()
-    : ast_node() {}
-
-ast_node_mark::ast_node_mark(const ast_node_mark &obj)
-    : ast_node(obj)
-{
-}
-
-ast_node_mark::ast_node_mark(__isl_take isl_ast_node *ptr)
-    : ast_node(ptr) {}
-
-ast_node_mark &ast_node_mark::operator=(ast_node_mark obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::checked::ctx ast_node_mark::ctx() const {
-  return isl::checked::ctx(isl_ast_node_get_ctx(ptr));
-}
-
-isl::checked::id ast_node_mark::id() const
+isl::checked::multi_id multi_id::set_at(int pos, isl::checked::id el) const
 {
-  auto res = isl_ast_node_mark_get_id(get());
+  auto res = isl_multi_id_set_at(copy(), pos, el.release());
   return manage(res);
 }
 
-isl::checked::id ast_node_mark::get_id() const
+isl::checked::multi_id multi_id::set_at(int pos, const std::string &el) const
 {
-  return id();
+  return this->set_at(pos, isl::checked::id(ctx(), el));
 }
 
-isl::checked::ast_node ast_node_mark::node() const
+class size multi_id::size() const
 {
-  auto res = isl_ast_node_mark_get_node(get());
+  auto res = isl_multi_id_size(get());
   return manage(res);
 }
 
-isl::checked::ast_node ast_node_mark::get_node() const
-{
-  return node();
-}
-
-inline std::ostream &operator<<(std::ostream &os, const ast_node_mark &obj)
-{
-  char *str = isl_ast_node_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
-}
-
-// implementations for isl::ast_node_user
-ast_node_user::ast_node_user()
-    : ast_node() {}
-
-ast_node_user::ast_node_user(const ast_node_user &obj)
-    : ast_node(obj)
-{
-}
-
-ast_node_user::ast_node_user(__isl_take isl_ast_node *ptr)
-    : ast_node(ptr) {}
-
-ast_node_user &ast_node_user::operator=(ast_node_user obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::checked::ctx ast_node_user::ctx() const {
-  return isl::checked::ctx(isl_ast_node_get_ctx(ptr));
-}
-
-isl::checked::ast_expr ast_node_user::expr() const
+isl::checked::space multi_id::space() const
 {
-  auto res = isl_ast_node_user_get_expr(get());
+  auto res = isl_multi_id_get_space(get());
   return manage(res);
 }
 
-isl::checked::ast_expr ast_node_user::get_expr() const
+isl::checked::space multi_id::get_space() const
 {
-  return expr();
+  return space();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_node_user &obj)
+inline std::ostream &operator<<(std::ostream &os, const multi_id &obj)
 {
-  char *str = isl_ast_node_to_str(obj.get());
+  char *str = isl_multi_id_to_str(obj.get());
   if (!str) {
     os.setstate(std::ios_base::badbit);
     return os;
@@ -5424,560 +10839,633 @@ inline std::ostream &operator<<(std::ostream &os, const ast_node_user &obj)
   return os;
 }
 
-// implementations for isl::basic_map
-basic_map manage(__isl_take isl_basic_map *ptr) {
-  return basic_map(ptr);
+// implementations for isl::multi_pw_aff
+multi_pw_aff manage(__isl_take isl_multi_pw_aff *ptr) {
+  return multi_pw_aff(ptr);
 }
-basic_map manage_copy(__isl_keep isl_basic_map *ptr) {
-  ptr = isl_basic_map_copy(ptr);
-  return basic_map(ptr);
+multi_pw_aff manage_copy(__isl_keep isl_multi_pw_aff *ptr) {
+  ptr = isl_multi_pw_aff_copy(ptr);
+  return multi_pw_aff(ptr);
 }
 
-basic_map::basic_map()
+multi_pw_aff::multi_pw_aff()
     : ptr(nullptr) {}
 
-basic_map::basic_map(const basic_map &obj)
+multi_pw_aff::multi_pw_aff(const multi_pw_aff &obj)
     : ptr(nullptr)
 {
   ptr = obj.copy();
 }
 
-basic_map::basic_map(__isl_take isl_basic_map *ptr)
+multi_pw_aff::multi_pw_aff(__isl_take isl_multi_pw_aff *ptr)
     : ptr(ptr) {}
 
-basic_map::basic_map(isl::checked::ctx ctx, const std::string &str)
+multi_pw_aff::multi_pw_aff(isl::checked::aff aff)
 {
-  auto res = isl_basic_map_read_from_str(ctx.release(), str.c_str());
+  auto res = isl_multi_pw_aff_from_aff(aff.release());
   ptr = res;
 }
 
-basic_map &basic_map::operator=(basic_map obj) {
+multi_pw_aff::multi_pw_aff(isl::checked::multi_aff ma)
+{
+  auto res = isl_multi_pw_aff_from_multi_aff(ma.release());
+  ptr = res;
+}
+
+multi_pw_aff::multi_pw_aff(isl::checked::pw_aff pa)
+{
+  auto res = isl_multi_pw_aff_from_pw_aff(pa.release());
+  ptr = res;
+}
+
+multi_pw_aff::multi_pw_aff(isl::checked::space space, isl::checked::pw_aff_list list)
+{
+  auto res = isl_multi_pw_aff_from_pw_aff_list(space.release(), list.release());
+  ptr = res;
+}
+
+multi_pw_aff::multi_pw_aff(isl::checked::pw_multi_aff pma)
+{
+  auto res = isl_multi_pw_aff_from_pw_multi_aff(pma.release());
+  ptr = res;
+}
+
+multi_pw_aff::multi_pw_aff(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_multi_pw_aff_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
+multi_pw_aff &multi_pw_aff::operator=(multi_pw_aff obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-basic_map::~basic_map() {
+multi_pw_aff::~multi_pw_aff() {
   if (ptr)
-    isl_basic_map_free(ptr);
+    isl_multi_pw_aff_free(ptr);
 }
 
-__isl_give isl_basic_map *basic_map::copy() const & {
-  return isl_basic_map_copy(ptr);
+__isl_give isl_multi_pw_aff *multi_pw_aff::copy() const & {
+  return isl_multi_pw_aff_copy(ptr);
 }
 
-__isl_keep isl_basic_map *basic_map::get() const {
+__isl_keep isl_multi_pw_aff *multi_pw_aff::get() const {
   return ptr;
 }
 
-__isl_give isl_basic_map *basic_map::release() {
-  isl_basic_map *tmp = ptr;
+__isl_give isl_multi_pw_aff *multi_pw_aff::release() {
+  isl_multi_pw_aff *tmp = ptr;
   ptr = nullptr;
   return tmp;
 }
 
-bool basic_map::is_null() const {
+bool multi_pw_aff::is_null() const {
   return ptr == nullptr;
 }
 
-isl::checked::ctx basic_map::ctx() const {
-  return isl::checked::ctx(isl_basic_map_get_ctx(ptr));
+isl::checked::ctx multi_pw_aff::ctx() const {
+  return isl::checked::ctx(isl_multi_pw_aff_get_ctx(ptr));
 }
 
-isl::checked::basic_map basic_map::affine_hull() const
+isl::checked::multi_pw_aff multi_pw_aff::add(isl::checked::multi_pw_aff multi2) const
 {
-  auto res = isl_basic_map_affine_hull(copy());
+  auto res = isl_multi_pw_aff_add(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::basic_map basic_map::apply_domain(isl::checked::basic_map bmap2) const
+isl::checked::multi_union_pw_aff multi_pw_aff::add(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  auto res = isl_basic_map_apply_domain(copy(), bmap2.release());
-  return manage(res);
+  return isl::checked::multi_union_pw_aff(*this).add(multi2);
 }
 
-isl::checked::basic_map basic_map::apply_range(isl::checked::basic_map bmap2) const
+isl::checked::multi_pw_aff multi_pw_aff::add(const isl::checked::aff &multi2) const
 {
-  auto res = isl_basic_map_apply_range(copy(), bmap2.release());
-  return manage(res);
+  return this->add(isl::checked::multi_pw_aff(multi2));
 }
 
-isl::checked::basic_set basic_map::deltas() const
+isl::checked::multi_pw_aff multi_pw_aff::add(const isl::checked::multi_aff &multi2) const
 {
-  auto res = isl_basic_map_deltas(copy());
-  return manage(res);
+  return this->add(isl::checked::multi_pw_aff(multi2));
 }
 
-isl::checked::basic_map basic_map::detect_equalities() const
+isl::checked::multi_pw_aff multi_pw_aff::add(const isl::checked::pw_aff &multi2) const
 {
-  auto res = isl_basic_map_detect_equalities(copy());
-  return manage(res);
+  return this->add(isl::checked::multi_pw_aff(multi2));
 }
 
-isl::checked::basic_map basic_map::flatten() const
+isl::checked::multi_pw_aff multi_pw_aff::add(const isl::checked::pw_multi_aff &multi2) const
 {
-  auto res = isl_basic_map_flatten(copy());
-  return manage(res);
+  return this->add(isl::checked::multi_pw_aff(multi2));
 }
 
-isl::checked::basic_map basic_map::flatten_domain() const
+isl::checked::multi_pw_aff multi_pw_aff::add_constant(isl::checked::multi_val mv) const
 {
-  auto res = isl_basic_map_flatten_domain(copy());
+  auto res = isl_multi_pw_aff_add_constant_multi_val(copy(), mv.release());
   return manage(res);
 }
 
-isl::checked::basic_map basic_map::flatten_range() const
+isl::checked::multi_pw_aff multi_pw_aff::add_constant(isl::checked::val v) const
 {
-  auto res = isl_basic_map_flatten_range(copy());
+  auto res = isl_multi_pw_aff_add_constant_val(copy(), v.release());
   return manage(res);
 }
 
-isl::checked::basic_map basic_map::gist(isl::checked::basic_map context) const
+isl::checked::multi_pw_aff multi_pw_aff::add_constant(long v) const
 {
-  auto res = isl_basic_map_gist(copy(), context.release());
-  return manage(res);
+  return this->add_constant(isl::checked::val(ctx(), v));
 }
 
-isl::checked::basic_map basic_map::intersect(isl::checked::basic_map bmap2) const
+isl::checked::map multi_pw_aff::as_map() const
 {
-  auto res = isl_basic_map_intersect(copy(), bmap2.release());
+  auto res = isl_multi_pw_aff_as_map(copy());
   return manage(res);
 }
 
-isl::checked::basic_map basic_map::intersect_domain(isl::checked::basic_set bset) const
+isl::checked::multi_aff multi_pw_aff::as_multi_aff() const
 {
-  auto res = isl_basic_map_intersect_domain(copy(), bset.release());
+  auto res = isl_multi_pw_aff_as_multi_aff(copy());
   return manage(res);
 }
 
-isl::checked::basic_map basic_map::intersect_range(isl::checked::basic_set bset) const
+isl::checked::set multi_pw_aff::as_set() const
 {
-  auto res = isl_basic_map_intersect_range(copy(), bset.release());
+  auto res = isl_multi_pw_aff_as_set(copy());
   return manage(res);
 }
 
-boolean basic_map::is_empty() const
+isl::checked::pw_aff multi_pw_aff::at(int pos) const
 {
-  auto res = isl_basic_map_is_empty(get());
+  auto res = isl_multi_pw_aff_get_at(get(), pos);
   return manage(res);
 }
 
-boolean basic_map::is_equal(const isl::checked::basic_map &bmap2) const
+isl::checked::pw_aff multi_pw_aff::get_at(int pos) const
 {
-  auto res = isl_basic_map_is_equal(get(), bmap2.get());
+  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());
   return manage(res);
 }
 
-boolean basic_map::is_subset(const isl::checked::basic_map &bmap2) const
+isl::checked::multi_pw_aff multi_pw_aff::bind_domain(isl::checked::multi_id tuple) const
 {
-  auto res = isl_basic_map_is_subset(get(), bmap2.get());
+  auto res = isl_multi_pw_aff_bind_domain(copy(), tuple.release());
   return manage(res);
 }
 
-isl::checked::map basic_map::lexmax() const
+isl::checked::multi_pw_aff multi_pw_aff::bind_domain_wrapped_domain(isl::checked::multi_id tuple) const
 {
-  auto res = isl_basic_map_lexmax(copy());
+  auto res = isl_multi_pw_aff_bind_domain_wrapped_domain(copy(), tuple.release());
   return manage(res);
 }
 
-isl::checked::map basic_map::lexmin() const
+isl::checked::multi_pw_aff multi_pw_aff::coalesce() const
 {
-  auto res = isl_basic_map_lexmin(copy());
+  auto res = isl_multi_pw_aff_coalesce(copy());
   return manage(res);
 }
 
-isl::checked::basic_map basic_map::reverse() const
+isl::checked::set multi_pw_aff::domain() const
 {
-  auto res = isl_basic_map_reverse(copy());
+  auto res = isl_multi_pw_aff_domain(copy());
   return manage(res);
 }
 
-isl::checked::basic_map basic_map::sample() const
+isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(isl::checked::multi_pw_aff multi2) const
 {
-  auto res = isl_basic_map_sample(copy());
+  auto res = isl_multi_pw_aff_flat_range_product(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::map basic_map::unite(isl::checked::basic_map bmap2) 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_basic_map_union(copy(), bmap2.release());
+  return isl::checked::multi_union_pw_aff(*this).flat_range_product(multi2);
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(const isl::checked::aff &multi2) const
+{
+  return this->flat_range_product(isl::checked::multi_pw_aff(multi2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(const isl::checked::multi_aff &multi2) const
+{
+  return this->flat_range_product(isl::checked::multi_pw_aff(multi2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(const isl::checked::pw_aff &multi2) const
+{
+  return this->flat_range_product(isl::checked::multi_pw_aff(multi2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(const isl::checked::pw_multi_aff &multi2) const
+{
+  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
+{
+  auto res = isl_multi_pw_aff_gist(copy(), set.release());
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const basic_map &obj)
+isl::checked::multi_union_pw_aff multi_pw_aff::gist(const isl::checked::union_set &context) const
 {
-  char *str = isl_basic_map_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::multi_union_pw_aff(*this).gist(context);
 }
 
-// implementations for isl::basic_set
-basic_set manage(__isl_take isl_basic_set *ptr) {
-  return basic_set(ptr);
+isl::checked::multi_pw_aff multi_pw_aff::gist(const isl::checked::basic_set &set) const
+{
+  return this->gist(isl::checked::set(set));
 }
-basic_set manage_copy(__isl_keep isl_basic_set *ptr) {
-  ptr = isl_basic_set_copy(ptr);
-  return basic_set(ptr);
+
+isl::checked::multi_pw_aff multi_pw_aff::gist(const isl::checked::point &set) const
+{
+  return this->gist(isl::checked::set(set));
 }
 
-basic_set::basic_set()
-    : ptr(nullptr) {}
+boolean multi_pw_aff::has_range_tuple_id() const
+{
+  auto res = isl_multi_pw_aff_has_range_tuple_id(get());
+  return manage(res);
+}
 
-basic_set::basic_set(const basic_set &obj)
-    : ptr(nullptr)
+isl::checked::multi_pw_aff multi_pw_aff::identity() const
 {
-  ptr = obj.copy();
+  auto res = isl_multi_pw_aff_identity_multi_pw_aff(copy());
+  return manage(res);
 }
 
-basic_set::basic_set(__isl_take isl_basic_set *ptr)
-    : ptr(ptr) {}
+isl::checked::multi_pw_aff multi_pw_aff::identity_on_domain(isl::checked::space space)
+{
+  auto res = isl_multi_pw_aff_identity_on_domain_space(space.release());
+  return manage(res);
+}
 
-basic_set::basic_set(isl::checked::point pnt)
+isl::checked::multi_pw_aff multi_pw_aff::insert_domain(isl::checked::space domain) const
 {
-  auto res = isl_basic_set_from_point(pnt.release());
-  ptr = res;
+  auto res = isl_multi_pw_aff_insert_domain(copy(), domain.release());
+  return manage(res);
 }
 
-basic_set::basic_set(isl::checked::ctx ctx, const std::string &str)
+isl::checked::multi_pw_aff multi_pw_aff::intersect_domain(isl::checked::set domain) const
 {
-  auto res = isl_basic_set_read_from_str(ctx.release(), str.c_str());
-  ptr = res;
+  auto res = isl_multi_pw_aff_intersect_domain(copy(), domain.release());
+  return manage(res);
 }
 
-basic_set &basic_set::operator=(basic_set obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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);
 }
 
-basic_set::~basic_set() {
-  if (ptr)
-    isl_basic_set_free(ptr);
+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_give isl_basic_set *basic_set::copy() const & {
-  return isl_basic_set_copy(ptr);
+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_keep isl_basic_set *basic_set::get() const {
-  return ptr;
+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());
+  return manage(res);
 }
 
-__isl_give isl_basic_set *basic_set::release() {
-  isl_basic_set *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+boolean multi_pw_aff::involves_nan() const
+{
+  auto res = isl_multi_pw_aff_involves_nan(get());
+  return manage(res);
 }
 
-bool basic_set::is_null() const {
-  return ptr == nullptr;
+boolean multi_pw_aff::involves_param(const isl::checked::id &id) const
+{
+  auto res = isl_multi_pw_aff_involves_param_id(get(), id.get());
+  return manage(res);
 }
 
-isl::checked::ctx basic_set::ctx() const {
-  return isl::checked::ctx(isl_basic_set_get_ctx(ptr));
+boolean multi_pw_aff::involves_param(const std::string &id) const
+{
+  return this->involves_param(isl::checked::id(ctx(), id));
+}
+
+boolean multi_pw_aff::involves_param(const isl::checked::id_list &list) const
+{
+  auto res = isl_multi_pw_aff_involves_param_id_list(get(), list.get());
+  return manage(res);
 }
 
-isl::checked::basic_set basic_set::affine_hull() const
+boolean multi_pw_aff::isa_multi_aff() const
 {
-  auto res = isl_basic_set_affine_hull(copy());
+  auto res = isl_multi_pw_aff_isa_multi_aff(get());
   return manage(res);
 }
 
-isl::checked::basic_set basic_set::apply(isl::checked::basic_map bmap) const
+isl::checked::pw_aff_list multi_pw_aff::list() const
 {
-  auto res = isl_basic_set_apply(copy(), bmap.release());
+  auto res = isl_multi_pw_aff_get_list(get());
   return manage(res);
 }
 
-isl::checked::basic_set basic_set::detect_equalities() const
+isl::checked::pw_aff_list multi_pw_aff::get_list() const
 {
-  auto res = isl_basic_set_detect_equalities(copy());
-  return manage(res);
+  return list();
 }
 
-isl::checked::val basic_set::dim_max_val(int pos) const
+isl::checked::multi_pw_aff multi_pw_aff::max(isl::checked::multi_pw_aff multi2) const
 {
-  auto res = isl_basic_set_dim_max_val(copy(), pos);
+  auto res = isl_multi_pw_aff_max(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::basic_set basic_set::flatten() const
+isl::checked::multi_val multi_pw_aff::max_multi_val() const
 {
-  auto res = isl_basic_set_flatten(copy());
+  auto res = isl_multi_pw_aff_max_multi_val(copy());
   return manage(res);
 }
 
-isl::checked::basic_set basic_set::gist(isl::checked::basic_set context) const
+isl::checked::multi_pw_aff multi_pw_aff::min(isl::checked::multi_pw_aff multi2) const
 {
-  auto res = isl_basic_set_gist(copy(), context.release());
+  auto res = isl_multi_pw_aff_min(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::basic_set basic_set::intersect(isl::checked::basic_set bset2) const
+isl::checked::multi_val multi_pw_aff::min_multi_val() const
 {
-  auto res = isl_basic_set_intersect(copy(), bset2.release());
+  auto res = isl_multi_pw_aff_min_multi_val(copy());
   return manage(res);
 }
 
-isl::checked::basic_set basic_set::intersect_params(isl::checked::basic_set bset2) const
+isl::checked::multi_pw_aff multi_pw_aff::neg() const
 {
-  auto res = isl_basic_set_intersect_params(copy(), bset2.release());
+  auto res = isl_multi_pw_aff_neg(copy());
   return manage(res);
 }
 
-boolean basic_set::is_empty() const
+boolean multi_pw_aff::plain_is_equal(const isl::checked::multi_pw_aff &multi2) const
 {
-  auto res = isl_basic_set_is_empty(get());
+  auto res = isl_multi_pw_aff_plain_is_equal(get(), multi2.get());
   return manage(res);
 }
 
-boolean basic_set::is_equal(const isl::checked::basic_set &bset2) const
+boolean multi_pw_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  auto res = isl_basic_set_is_equal(get(), bset2.get());
-  return manage(res);
+  return isl::checked::multi_union_pw_aff(*this).plain_is_equal(multi2);
 }
 
-boolean basic_set::is_subset(const isl::checked::basic_set &bset2) const
+boolean multi_pw_aff::plain_is_equal(const isl::checked::aff &multi2) const
 {
-  auto res = isl_basic_set_is_subset(get(), bset2.get());
-  return manage(res);
+  return this->plain_is_equal(isl::checked::multi_pw_aff(multi2));
 }
 
-boolean basic_set::is_wrapping() const
+boolean multi_pw_aff::plain_is_equal(const isl::checked::multi_aff &multi2) const
 {
-  auto res = isl_basic_set_is_wrapping(get());
-  return manage(res);
+  return this->plain_is_equal(isl::checked::multi_pw_aff(multi2));
 }
 
-isl::checked::set basic_set::lexmax() const
+boolean multi_pw_aff::plain_is_equal(const isl::checked::pw_aff &multi2) const
 {
-  auto res = isl_basic_set_lexmax(copy());
-  return manage(res);
+  return this->plain_is_equal(isl::checked::multi_pw_aff(multi2));
 }
 
-isl::checked::set basic_set::lexmin() const
+boolean multi_pw_aff::plain_is_equal(const isl::checked::pw_multi_aff &multi2) const
 {
-  auto res = isl_basic_set_lexmin(copy());
-  return manage(res);
+  return this->plain_is_equal(isl::checked::multi_pw_aff(multi2));
 }
 
-isl::checked::basic_set basic_set::params() const
+isl::checked::multi_pw_aff multi_pw_aff::product(isl::checked::multi_pw_aff multi2) const
 {
-  auto res = isl_basic_set_params(copy());
+  auto res = isl_multi_pw_aff_product(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::basic_set basic_set::sample() const
+isl::checked::multi_pw_aff multi_pw_aff::pullback(isl::checked::multi_aff ma) const
 {
-  auto res = isl_basic_set_sample(copy());
+  auto res = isl_multi_pw_aff_pullback_multi_aff(copy(), ma.release());
   return manage(res);
 }
 
-isl::checked::point basic_set::sample_point() const
+isl::checked::multi_pw_aff multi_pw_aff::pullback(isl::checked::multi_pw_aff mpa2) const
 {
-  auto res = isl_basic_set_sample_point(copy());
+  auto res = isl_multi_pw_aff_pullback_multi_pw_aff(copy(), mpa2.release());
   return manage(res);
 }
 
-isl::checked::set basic_set::unite(isl::checked::basic_set bset2) const
+isl::checked::multi_pw_aff multi_pw_aff::pullback(isl::checked::pw_multi_aff pma) const
 {
-  auto res = isl_basic_set_union(copy(), bset2.release());
+  auto res = isl_multi_pw_aff_pullback_pw_multi_aff(copy(), pma.release());
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const basic_set &obj)
+isl::checked::multi_union_pw_aff multi_pw_aff::pullback(const isl::checked::union_pw_multi_aff &upma) const
 {
-  char *str = isl_basic_set_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::multi_union_pw_aff(*this).pullback(upma);
 }
 
-// implementations for isl::fixed_box
-fixed_box manage(__isl_take isl_fixed_box *ptr) {
-  return fixed_box(ptr);
+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);
 }
-fixed_box manage_copy(__isl_keep isl_fixed_box *ptr) {
-  ptr = isl_fixed_box_copy(ptr);
-  return fixed_box(ptr);
+
+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);
 }
 
-fixed_box::fixed_box()
-    : ptr(nullptr) {}
+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));
+}
 
-fixed_box::fixed_box(const fixed_box &obj)
-    : ptr(nullptr)
+isl::checked::multi_pw_aff multi_pw_aff::range_product(const isl::checked::multi_aff &multi2) const
 {
-  ptr = obj.copy();
+  return this->range_product(isl::checked::multi_pw_aff(multi2));
 }
 
-fixed_box::fixed_box(__isl_take isl_fixed_box *ptr)
-    : ptr(ptr) {}
+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));
+}
 
-fixed_box &fixed_box::operator=(fixed_box obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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));
 }
 
-fixed_box::~fixed_box() {
-  if (ptr)
-    isl_fixed_box_free(ptr);
+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_give isl_fixed_box *fixed_box::copy() const & {
-  return isl_fixed_box_copy(ptr);
+isl::checked::id multi_pw_aff::get_range_tuple_id() const
+{
+  return range_tuple_id();
 }
 
-__isl_keep isl_fixed_box *fixed_box::get() const {
-  return ptr;
+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_give isl_fixed_box *fixed_box::release() {
-  isl_fixed_box *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+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());
+  return manage(res);
 }
 
-bool fixed_box::is_null() const {
-  return ptr == nullptr;
+isl::checked::multi_pw_aff multi_pw_aff::scale(isl::checked::val v) const
+{
+  auto res = isl_multi_pw_aff_scale_val(copy(), v.release());
+  return manage(res);
 }
 
-isl::checked::ctx fixed_box::ctx() const {
-  return isl::checked::ctx(isl_fixed_box_get_ctx(ptr));
+isl::checked::multi_pw_aff multi_pw_aff::scale(long v) const
+{
+  return this->scale(isl::checked::val(ctx(), v));
 }
 
-isl::checked::multi_aff fixed_box::offset() const
+isl::checked::multi_pw_aff multi_pw_aff::scale_down(isl::checked::multi_val mv) const
 {
-  auto res = isl_fixed_box_get_offset(get());
+  auto res = isl_multi_pw_aff_scale_down_multi_val(copy(), mv.release());
   return manage(res);
 }
 
-isl::checked::multi_aff fixed_box::get_offset() const
+isl::checked::multi_pw_aff multi_pw_aff::scale_down(isl::checked::val v) const
 {
-  return offset();
+  auto res = isl_multi_pw_aff_scale_down_val(copy(), v.release());
+  return manage(res);
 }
 
-isl::checked::multi_val fixed_box::size() const
+isl::checked::multi_pw_aff multi_pw_aff::scale_down(long v) const
 {
-  auto res = isl_fixed_box_get_size(get());
+  return this->scale_down(isl::checked::val(ctx(), v));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::set_at(int pos, isl::checked::pw_aff el) const
+{
+  auto res = isl_multi_pw_aff_set_at(copy(), pos, el.release());
   return manage(res);
 }
 
-isl::checked::multi_val fixed_box::get_size() const
+isl::checked::multi_union_pw_aff multi_pw_aff::set_at(int pos, const isl::checked::union_pw_aff &el) const
 {
-  return size();
+  return isl::checked::multi_union_pw_aff(*this).set_at(pos, el);
 }
 
-isl::checked::space fixed_box::space() const
+isl::checked::multi_pw_aff multi_pw_aff::set_range_tuple(isl::checked::id id) const
 {
-  auto res = isl_fixed_box_get_space(get());
+  auto res = isl_multi_pw_aff_set_range_tuple_id(copy(), id.release());
   return manage(res);
 }
 
-isl::checked::space fixed_box::get_space() const
+isl::checked::multi_pw_aff multi_pw_aff::set_range_tuple(const std::string &id) const
 {
-  return space();
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
 }
 
-boolean fixed_box::is_valid() const
+class size multi_pw_aff::size() const
 {
-  auto res = isl_fixed_box_is_valid(get());
+  auto res = isl_multi_pw_aff_size(get());
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const fixed_box &obj)
+isl::checked::space multi_pw_aff::space() const
 {
-  char *str = isl_fixed_box_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  auto res = isl_multi_pw_aff_get_space(get());
+  return manage(res);
 }
 
-// implementations for isl::id
-id manage(__isl_take isl_id *ptr) {
-  return id(ptr);
+isl::checked::space multi_pw_aff::get_space() const
+{
+  return space();
 }
-id manage_copy(__isl_keep isl_id *ptr) {
-  ptr = isl_id_copy(ptr);
-  return id(ptr);
+
+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);
 }
 
-id::id()
-    : ptr(nullptr) {}
+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);
+}
 
-id::id(const id &obj)
-    : ptr(nullptr)
+isl::checked::multi_pw_aff multi_pw_aff::sub(const isl::checked::aff &multi2) const
 {
-  ptr = obj.copy();
+  return this->sub(isl::checked::multi_pw_aff(multi2));
 }
 
-id::id(__isl_take isl_id *ptr)
-    : ptr(ptr) {}
+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));
+}
 
-id::id(isl::checked::ctx ctx, const std::string &str)
+isl::checked::multi_pw_aff multi_pw_aff::sub(const isl::checked::pw_aff &multi2) const
 {
-  auto res = isl_id_read_from_str(ctx.release(), str.c_str());
-  ptr = res;
+  return this->sub(isl::checked::multi_pw_aff(multi2));
 }
 
-id &id::operator=(id obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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));
 }
 
-id::~id() {
-  if (ptr)
-    isl_id_free(ptr);
+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());
+  return manage(res);
 }
 
-__isl_give isl_id *id::copy() const & {
-  return isl_id_copy(ptr);
+isl::checked::multi_pw_aff multi_pw_aff::union_add(isl::checked::multi_pw_aff mpa2) const
+{
+  auto res = isl_multi_pw_aff_union_add(copy(), mpa2.release());
+  return manage(res);
 }
 
-__isl_keep isl_id *id::get() const {
-  return ptr;
+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_give isl_id *id::release() {
-  isl_id *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+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));
 }
 
-bool id::is_null() const {
-  return ptr == nullptr;
+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::ctx id::ctx() const {
-  return isl::checked::ctx(isl_id_get_ctx(ptr));
+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));
 }
 
-std::string id::name() const
+isl::checked::multi_pw_aff multi_pw_aff::union_add(const isl::checked::pw_multi_aff &mpa2) const
 {
-  auto res = isl_id_get_name(get());
-  std::string tmp(res);
-  return tmp;
+  return this->union_add(isl::checked::multi_pw_aff(mpa2));
 }
 
-std::string id::get_name() const
+isl::checked::multi_pw_aff multi_pw_aff::zero(isl::checked::space space)
 {
-  return name();
+  auto res = isl_multi_pw_aff_zero(space.release());
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const id &obj)
+inline std::ostream &operator<<(std::ostream &os, const multi_pw_aff &obj)
 {
-  char *str = isl_id_to_str(obj.get());
+  char *str = isl_multi_pw_aff_to_str(obj.get());
   if (!str) {
     os.setstate(std::ios_base::badbit);
     return os;
@@ -5987,1163 +11475,1094 @@ inline std::ostream &operator<<(std::ostream &os, const id &obj)
   return os;
 }
 
-// implementations for isl::id_list
-id_list manage(__isl_take isl_id_list *ptr) {
-  return id_list(ptr);
+// implementations for isl::multi_union_pw_aff
+multi_union_pw_aff manage(__isl_take isl_multi_union_pw_aff *ptr) {
+  return multi_union_pw_aff(ptr);
 }
-id_list manage_copy(__isl_keep isl_id_list *ptr) {
-  ptr = isl_id_list_copy(ptr);
-  return id_list(ptr);
+multi_union_pw_aff manage_copy(__isl_keep isl_multi_union_pw_aff *ptr) {
+  ptr = isl_multi_union_pw_aff_copy(ptr);
+  return multi_union_pw_aff(ptr);
 }
 
-id_list::id_list()
+multi_union_pw_aff::multi_union_pw_aff()
     : ptr(nullptr) {}
 
-id_list::id_list(const id_list &obj)
+multi_union_pw_aff::multi_union_pw_aff(const multi_union_pw_aff &obj)
     : ptr(nullptr)
 {
   ptr = obj.copy();
 }
 
-id_list::id_list(__isl_take isl_id_list *ptr)
+multi_union_pw_aff::multi_union_pw_aff(__isl_take isl_multi_union_pw_aff *ptr)
     : ptr(ptr) {}
 
-id_list::id_list(isl::checked::ctx ctx, int n)
+multi_union_pw_aff::multi_union_pw_aff(isl::checked::multi_pw_aff mpa)
 {
-  auto res = isl_id_list_alloc(ctx.release(), n);
+  auto res = isl_multi_union_pw_aff_from_multi_pw_aff(mpa.release());
   ptr = res;
 }
 
-id_list::id_list(isl::checked::id el)
+multi_union_pw_aff::multi_union_pw_aff(isl::checked::union_pw_aff upa)
 {
-  auto res = isl_id_list_from_id(el.release());
+  auto res = isl_multi_union_pw_aff_from_union_pw_aff(upa.release());
   ptr = res;
 }
 
-id_list &id_list::operator=(id_list obj) {
+multi_union_pw_aff::multi_union_pw_aff(isl::checked::space space, isl::checked::union_pw_aff_list list)
+{
+  auto res = isl_multi_union_pw_aff_from_union_pw_aff_list(space.release(), list.release());
+  ptr = res;
+}
+
+multi_union_pw_aff::multi_union_pw_aff(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_multi_union_pw_aff_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
+multi_union_pw_aff &multi_union_pw_aff::operator=(multi_union_pw_aff obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-id_list::~id_list() {
+multi_union_pw_aff::~multi_union_pw_aff() {
   if (ptr)
-    isl_id_list_free(ptr);
+    isl_multi_union_pw_aff_free(ptr);
 }
 
-__isl_give isl_id_list *id_list::copy() const & {
-  return isl_id_list_copy(ptr);
+__isl_give isl_multi_union_pw_aff *multi_union_pw_aff::copy() const & {
+  return isl_multi_union_pw_aff_copy(ptr);
 }
 
-__isl_keep isl_id_list *id_list::get() const {
+__isl_keep isl_multi_union_pw_aff *multi_union_pw_aff::get() const {
   return ptr;
 }
 
-__isl_give isl_id_list *id_list::release() {
-  isl_id_list *tmp = ptr;
+__isl_give isl_multi_union_pw_aff *multi_union_pw_aff::release() {
+  isl_multi_union_pw_aff *tmp = ptr;
   ptr = nullptr;
   return tmp;
 }
 
-bool id_list::is_null() const {
+bool multi_union_pw_aff::is_null() const {
   return ptr == nullptr;
 }
 
-isl::checked::ctx id_list::ctx() const {
-  return isl::checked::ctx(isl_id_list_get_ctx(ptr));
+isl::checked::ctx multi_union_pw_aff::ctx() const {
+  return isl::checked::ctx(isl_multi_union_pw_aff_get_ctx(ptr));
 }
 
-isl::checked::id_list id_list::add(isl::checked::id el) const
+isl::checked::multi_union_pw_aff multi_union_pw_aff::add(isl::checked::multi_union_pw_aff multi2) const
 {
-  auto res = isl_id_list_add(copy(), el.release());
+  auto res = isl_multi_union_pw_aff_add(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::id_list id_list::add(const std::string &el) const
+isl::checked::union_pw_aff multi_union_pw_aff::at(int pos) const
 {
-  return this->add(isl::checked::id(ctx(), el));
+  auto res = isl_multi_union_pw_aff_get_at(get(), pos);
+  return manage(res);
 }
 
-isl::checked::id_list id_list::clear() const
+isl::checked::union_pw_aff multi_union_pw_aff::get_at(int pos) const
 {
-  auto res = isl_id_list_clear(copy());
+  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());
   return manage(res);
 }
 
-isl::checked::id_list id_list::concat(isl::checked::id_list list2) const
+isl::checked::multi_union_pw_aff multi_union_pw_aff::coalesce() const
 {
-  auto res = isl_id_list_concat(copy(), list2.release());
+  auto res = isl_multi_union_pw_aff_coalesce(copy());
   return manage(res);
 }
 
-isl::checked::id_list id_list::drop(unsigned int first, unsigned int n) const
+isl::checked::union_set multi_union_pw_aff::domain() const
 {
-  auto res = isl_id_list_drop(copy(), first, n);
+  auto res = isl_multi_union_pw_aff_domain(copy());
   return manage(res);
 }
 
-stat id_list::foreach(const std::function<stat(isl::checked::id)> &fn) const
+isl::checked::multi_union_pw_aff multi_union_pw_aff::flat_range_product(isl::checked::multi_union_pw_aff multi2) const
 {
-  struct fn_data {
-    std::function<stat(isl::checked::id)> func;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_id *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_id_list_foreach(get(), fn_lambda, &fn_data);
+  auto res = isl_multi_union_pw_aff_flat_range_product(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::id id_list::at(int index) const
+isl::checked::multi_union_pw_aff multi_union_pw_aff::gist(isl::checked::union_set context) const
 {
-  auto res = isl_id_list_get_at(get(), index);
+  auto res = isl_multi_union_pw_aff_gist(copy(), context.release());
   return manage(res);
 }
 
-isl::checked::id id_list::get_at(int index) const
+boolean multi_union_pw_aff::has_range_tuple_id() const
 {
-  return at(index);
+  auto res = isl_multi_union_pw_aff_has_range_tuple_id(get());
+  return manage(res);
 }
 
-isl::checked::id_list id_list::insert(unsigned int pos, isl::checked::id el) const
+isl::checked::multi_union_pw_aff multi_union_pw_aff::intersect_domain(isl::checked::union_set uset) const
 {
-  auto res = isl_id_list_insert(copy(), pos, el.release());
+  auto res = isl_multi_union_pw_aff_intersect_domain(copy(), uset.release());
   return manage(res);
 }
 
-isl::checked::id_list id_list::insert(unsigned int pos, const std::string &el) const
+isl::checked::multi_union_pw_aff multi_union_pw_aff::intersect_params(isl::checked::set params) const
 {
-  return this->insert(pos, isl::checked::id(ctx(), el));
+  auto res = isl_multi_union_pw_aff_intersect_params(copy(), params.release());
+  return manage(res);
 }
 
-class size id_list::size() const
+boolean multi_union_pw_aff::involves_nan() const
 {
-  auto res = isl_id_list_size(get());
+  auto res = isl_multi_union_pw_aff_involves_nan(get());
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const id_list &obj)
+isl::checked::union_pw_aff_list multi_union_pw_aff::list() const
 {
-  char *str = isl_id_list_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  auto res = isl_multi_union_pw_aff_get_list(get());
+  return manage(res);
 }
 
-// implementations for isl::map
-map manage(__isl_take isl_map *ptr) {
-  return map(ptr);
+isl::checked::union_pw_aff_list multi_union_pw_aff::get_list() const
+{
+  return list();
 }
-map manage_copy(__isl_keep isl_map *ptr) {
-  ptr = isl_map_copy(ptr);
-  return map(ptr);
+
+isl::checked::multi_union_pw_aff multi_union_pw_aff::neg() const
+{
+  auto res = isl_multi_union_pw_aff_neg(copy());
+  return manage(res);
 }
 
-map::map()
-    : ptr(nullptr) {}
+boolean multi_union_pw_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  auto res = isl_multi_union_pw_aff_plain_is_equal(get(), multi2.get());
+  return manage(res);
+}
 
-map::map(const map &obj)
-    : ptr(nullptr)
+isl::checked::multi_union_pw_aff multi_union_pw_aff::pullback(isl::checked::union_pw_multi_aff upma) const
 {
-  ptr = obj.copy();
+  auto res = isl_multi_union_pw_aff_pullback_union_pw_multi_aff(copy(), upma.release());
+  return manage(res);
 }
 
-map::map(__isl_take isl_map *ptr)
-    : ptr(ptr) {}
+isl::checked::multi_union_pw_aff multi_union_pw_aff::range_product(isl::checked::multi_union_pw_aff multi2) const
+{
+  auto res = isl_multi_union_pw_aff_range_product(copy(), multi2.release());
+  return manage(res);
+}
 
-map::map(isl::checked::basic_map bmap)
+isl::checked::id multi_union_pw_aff::range_tuple_id() const
 {
-  auto res = isl_map_from_basic_map(bmap.release());
-  ptr = res;
+  auto res = isl_multi_union_pw_aff_get_range_tuple_id(get());
+  return manage(res);
 }
 
-map::map(isl::checked::ctx ctx, const std::string &str)
+isl::checked::id multi_union_pw_aff::get_range_tuple_id() const
 {
-  auto res = isl_map_read_from_str(ctx.release(), str.c_str());
-  ptr = res;
+  return range_tuple_id();
 }
 
-map &map::operator=(map obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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);
 }
 
-map::~map() {
-  if (ptr)
-    isl_map_free(ptr);
+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());
+  return manage(res);
 }
 
-__isl_give isl_map *map::copy() const & {
-  return isl_map_copy(ptr);
+isl::checked::multi_union_pw_aff multi_union_pw_aff::scale(isl::checked::val v) const
+{
+  auto res = isl_multi_union_pw_aff_scale_val(copy(), v.release());
+  return manage(res);
 }
 
-__isl_keep isl_map *map::get() const {
-  return ptr;
+isl::checked::multi_union_pw_aff multi_union_pw_aff::scale(long v) const
+{
+  return this->scale(isl::checked::val(ctx(), v));
 }
 
-__isl_give isl_map *map::release() {
-  isl_map *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+isl::checked::multi_union_pw_aff multi_union_pw_aff::scale_down(isl::checked::multi_val mv) const
+{
+  auto res = isl_multi_union_pw_aff_scale_down_multi_val(copy(), mv.release());
+  return manage(res);
 }
 
-bool map::is_null() const {
-  return ptr == nullptr;
+isl::checked::multi_union_pw_aff multi_union_pw_aff::scale_down(isl::checked::val v) const
+{
+  auto res = isl_multi_union_pw_aff_scale_down_val(copy(), v.release());
+  return manage(res);
 }
 
-isl::checked::ctx map::ctx() const {
-  return isl::checked::ctx(isl_map_get_ctx(ptr));
+isl::checked::multi_union_pw_aff multi_union_pw_aff::scale_down(long v) const
+{
+  return this->scale_down(isl::checked::val(ctx(), v));
 }
 
-isl::checked::basic_map map::affine_hull() const
+isl::checked::multi_union_pw_aff multi_union_pw_aff::set_at(int pos, isl::checked::union_pw_aff el) const
 {
-  auto res = isl_map_affine_hull(copy());
+  auto res = isl_multi_union_pw_aff_set_at(copy(), pos, el.release());
   return manage(res);
 }
 
-isl::checked::map map::apply_domain(isl::checked::map map2) const
+isl::checked::multi_union_pw_aff multi_union_pw_aff::set_range_tuple(isl::checked::id id) const
 {
-  auto res = isl_map_apply_domain(copy(), map2.release());
+  auto res = isl_multi_union_pw_aff_set_range_tuple_id(copy(), id.release());
   return manage(res);
 }
 
-isl::checked::map map::apply_range(isl::checked::map map2) const
+isl::checked::multi_union_pw_aff multi_union_pw_aff::set_range_tuple(const std::string &id) const
 {
-  auto res = isl_map_apply_range(copy(), map2.release());
-  return manage(res);
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
 }
 
-isl::checked::set map::bind_domain(isl::checked::multi_id tuple) const
+class size multi_union_pw_aff::size() const
 {
-  auto res = isl_map_bind_domain(copy(), tuple.release());
+  auto res = isl_multi_union_pw_aff_size(get());
   return manage(res);
 }
 
-isl::checked::set map::bind_range(isl::checked::multi_id tuple) const
+isl::checked::space multi_union_pw_aff::space() const
 {
-  auto res = isl_map_bind_range(copy(), tuple.release());
+  auto res = isl_multi_union_pw_aff_get_space(get());
   return manage(res);
 }
 
-isl::checked::map map::coalesce() const
+isl::checked::space multi_union_pw_aff::get_space() const
 {
-  auto res = isl_map_coalesce(copy());
-  return manage(res);
+  return space();
 }
 
-isl::checked::map map::complement() const
+isl::checked::multi_union_pw_aff multi_union_pw_aff::sub(isl::checked::multi_union_pw_aff multi2) const
 {
-  auto res = isl_map_complement(copy());
+  auto res = isl_multi_union_pw_aff_sub(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::map map::curry() const
+isl::checked::multi_union_pw_aff multi_union_pw_aff::union_add(isl::checked::multi_union_pw_aff mupa2) const
 {
-  auto res = isl_map_curry(copy());
+  auto res = isl_multi_union_pw_aff_union_add(copy(), mupa2.release());
   return manage(res);
 }
 
-isl::checked::set map::deltas() const
+isl::checked::multi_union_pw_aff multi_union_pw_aff::zero(isl::checked::space space)
 {
-  auto res = isl_map_deltas(copy());
+  auto res = isl_multi_union_pw_aff_zero(space.release());
   return manage(res);
 }
 
-isl::checked::map map::detect_equalities() const
+inline std::ostream &operator<<(std::ostream &os, const multi_union_pw_aff &obj)
 {
-  auto res = isl_map_detect_equalities(copy());
-  return manage(res);
+  char *str = isl_multi_union_pw_aff_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::multi_val
+multi_val manage(__isl_take isl_multi_val *ptr) {
+  return multi_val(ptr);
+}
+multi_val manage_copy(__isl_keep isl_multi_val *ptr) {
+  ptr = isl_multi_val_copy(ptr);
+  return multi_val(ptr);
 }
 
-isl::checked::set map::domain() const
-{
-  auto res = isl_map_domain(copy());
-  return manage(res);
-}
+multi_val::multi_val()
+    : ptr(nullptr) {}
 
-isl::checked::map map::domain_factor_domain() const
+multi_val::multi_val(const multi_val &obj)
+    : ptr(nullptr)
 {
-  auto res = isl_map_domain_factor_domain(copy());
-  return manage(res);
+  ptr = obj.copy();
 }
 
-isl::checked::map map::domain_factor_range() const
+multi_val::multi_val(__isl_take isl_multi_val *ptr)
+    : ptr(ptr) {}
+
+multi_val::multi_val(isl::checked::space space, isl::checked::val_list list)
 {
-  auto res = isl_map_domain_factor_range(copy());
-  return manage(res);
+  auto res = isl_multi_val_from_val_list(space.release(), list.release());
+  ptr = res;
 }
 
-isl::checked::map map::domain_product(isl::checked::map map2) const
+multi_val::multi_val(isl::checked::ctx ctx, const std::string &str)
 {
-  auto res = isl_map_domain_product(copy(), map2.release());
-  return manage(res);
+  auto res = isl_multi_val_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
 }
 
-isl::checked::map map::empty(isl::checked::space space)
-{
-  auto res = isl_map_empty(space.release());
-  return manage(res);
+multi_val &multi_val::operator=(multi_val obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
 }
 
-isl::checked::map map::eq_at(isl::checked::multi_pw_aff mpa) const
-{
-  auto res = isl_map_eq_at_multi_pw_aff(copy(), mpa.release());
-  return manage(res);
+multi_val::~multi_val() {
+  if (ptr)
+    isl_multi_val_free(ptr);
 }
 
-isl::checked::map map::factor_domain() const
-{
-  auto res = isl_map_factor_domain(copy());
-  return manage(res);
+__isl_give isl_multi_val *multi_val::copy() const & {
+  return isl_multi_val_copy(ptr);
 }
 
-isl::checked::map map::factor_range() const
-{
-  auto res = isl_map_factor_range(copy());
-  return manage(res);
+__isl_keep isl_multi_val *multi_val::get() const {
+  return ptr;
 }
 
-isl::checked::map map::flatten() const
-{
-  auto res = isl_map_flatten(copy());
-  return manage(res);
+__isl_give isl_multi_val *multi_val::release() {
+  isl_multi_val *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
 }
 
-isl::checked::map map::flatten_domain() const
-{
-  auto res = isl_map_flatten_domain(copy());
-  return manage(res);
+bool multi_val::is_null() const {
+  return ptr == nullptr;
 }
 
-isl::checked::map map::flatten_range() const
-{
-  auto res = isl_map_flatten_range(copy());
-  return manage(res);
+isl::checked::ctx multi_val::ctx() const {
+  return isl::checked::ctx(isl_multi_val_get_ctx(ptr));
 }
 
-stat map::foreach_basic_map(const std::function<stat(isl::checked::basic_map)> &fn) const
+isl::checked::multi_val multi_val::add(isl::checked::multi_val multi2) const
 {
-  struct fn_data {
-    std::function<stat(isl::checked::basic_map)> func;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_basic_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_foreach_basic_map(get(), fn_lambda, &fn_data);
+  auto res = isl_multi_val_add(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::fixed_box map::range_simple_fixed_box_hull() const
+isl::checked::multi_val multi_val::add(isl::checked::val v) const
 {
-  auto res = isl_map_get_range_simple_fixed_box_hull(get());
+  auto res = isl_multi_val_add_val(copy(), v.release());
   return manage(res);
 }
 
-isl::checked::fixed_box map::get_range_simple_fixed_box_hull() const
+isl::checked::multi_val multi_val::add(long v) const
 {
-  return range_simple_fixed_box_hull();
+  return this->add(isl::checked::val(ctx(), v));
 }
 
-isl::checked::space map::space() const
+isl::checked::val multi_val::at(int pos) const
 {
-  auto res = isl_map_get_space(get());
+  auto res = isl_multi_val_get_at(get(), pos);
   return manage(res);
 }
 
-isl::checked::space map::get_space() const
+isl::checked::val multi_val::get_at(int pos) const
 {
-  return space();
+  return at(pos);
 }
 
-isl::checked::map map::gist(isl::checked::map context) const
+isl::checked::multi_val multi_val::flat_range_product(isl::checked::multi_val multi2) const
 {
-  auto res = isl_map_gist(copy(), context.release());
+  auto res = isl_multi_val_flat_range_product(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::map map::gist_domain(isl::checked::set context) const
+boolean multi_val::has_range_tuple_id() const
 {
-  auto res = isl_map_gist_domain(copy(), context.release());
+  auto res = isl_multi_val_has_range_tuple_id(get());
   return manage(res);
 }
 
-isl::checked::map map::intersect(isl::checked::map map2) const
+boolean multi_val::involves_nan() const
 {
-  auto res = isl_map_intersect(copy(), map2.release());
+  auto res = isl_multi_val_involves_nan(get());
   return manage(res);
 }
 
-isl::checked::map map::intersect_domain(isl::checked::set set) const
+isl::checked::val_list multi_val::list() const
 {
-  auto res = isl_map_intersect_domain(copy(), set.release());
+  auto res = isl_multi_val_get_list(get());
   return manage(res);
 }
 
-isl::checked::map map::intersect_domain_factor_domain(isl::checked::map factor) const
+isl::checked::val_list multi_val::get_list() const
 {
-  auto res = isl_map_intersect_domain_factor_domain(copy(), factor.release());
-  return manage(res);
+  return list();
 }
 
-isl::checked::map map::intersect_domain_factor_range(isl::checked::map factor) const
+isl::checked::multi_val multi_val::max(isl::checked::multi_val multi2) const
 {
-  auto res = isl_map_intersect_domain_factor_range(copy(), factor.release());
+  auto res = isl_multi_val_max(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::map map::intersect_params(isl::checked::set params) const
+isl::checked::multi_val multi_val::min(isl::checked::multi_val multi2) const
 {
-  auto res = isl_map_intersect_params(copy(), params.release());
+  auto res = isl_multi_val_min(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::map map::intersect_range(isl::checked::set set) const
+isl::checked::multi_val multi_val::neg() const
 {
-  auto res = isl_map_intersect_range(copy(), set.release());
+  auto res = isl_multi_val_neg(copy());
   return manage(res);
 }
 
-isl::checked::map map::intersect_range_factor_domain(isl::checked::map factor) const
+boolean multi_val::plain_is_equal(const isl::checked::multi_val &multi2) const
 {
-  auto res = isl_map_intersect_range_factor_domain(copy(), factor.release());
+  auto res = isl_multi_val_plain_is_equal(get(), multi2.get());
   return manage(res);
 }
 
-isl::checked::map map::intersect_range_factor_range(isl::checked::map factor) const
+isl::checked::multi_val multi_val::product(isl::checked::multi_val multi2) const
 {
-  auto res = isl_map_intersect_range_factor_range(copy(), factor.release());
+  auto res = isl_multi_val_product(copy(), multi2.release());
   return manage(res);
 }
 
-boolean map::is_bijective() const
+isl::checked::multi_val multi_val::range_product(isl::checked::multi_val multi2) const
 {
-  auto res = isl_map_is_bijective(get());
+  auto res = isl_multi_val_range_product(copy(), multi2.release());
   return manage(res);
 }
 
-boolean map::is_disjoint(const isl::checked::map &map2) const
+isl::checked::id multi_val::range_tuple_id() const
 {
-  auto res = isl_map_is_disjoint(get(), map2.get());
+  auto res = isl_multi_val_get_range_tuple_id(get());
   return manage(res);
 }
 
-boolean map::is_empty() const
+isl::checked::id multi_val::get_range_tuple_id() const
 {
-  auto res = isl_map_is_empty(get());
-  return manage(res);
+  return range_tuple_id();
 }
 
-boolean map::is_equal(const isl::checked::map &map2) const
+isl::checked::multi_val multi_val::reset_range_tuple_id() const
 {
-  auto res = isl_map_is_equal(get(), map2.get());
+  auto res = isl_multi_val_reset_range_tuple_id(copy());
   return manage(res);
 }
 
-boolean map::is_injective() const
+isl::checked::multi_val multi_val::scale(isl::checked::multi_val mv) const
 {
-  auto res = isl_map_is_injective(get());
+  auto res = isl_multi_val_scale_multi_val(copy(), mv.release());
   return manage(res);
 }
 
-boolean map::is_single_valued() const
+isl::checked::multi_val multi_val::scale(isl::checked::val v) const
 {
-  auto res = isl_map_is_single_valued(get());
+  auto res = isl_multi_val_scale_val(copy(), v.release());
   return manage(res);
 }
 
-boolean map::is_strict_subset(const isl::checked::map &map2) const
+isl::checked::multi_val multi_val::scale(long v) const
 {
-  auto res = isl_map_is_strict_subset(get(), map2.get());
-  return manage(res);
+  return this->scale(isl::checked::val(ctx(), v));
 }
 
-boolean map::is_subset(const isl::checked::map &map2) const
+isl::checked::multi_val multi_val::scale_down(isl::checked::multi_val mv) const
 {
-  auto res = isl_map_is_subset(get(), map2.get());
+  auto res = isl_multi_val_scale_down_multi_val(copy(), mv.release());
   return manage(res);
 }
 
-isl::checked::map map::lex_ge_at(isl::checked::multi_pw_aff mpa) const
+isl::checked::multi_val multi_val::scale_down(isl::checked::val v) const
 {
-  auto res = isl_map_lex_ge_at_multi_pw_aff(copy(), mpa.release());
+  auto res = isl_multi_val_scale_down_val(copy(), v.release());
   return manage(res);
 }
 
-isl::checked::map map::lex_gt_at(isl::checked::multi_pw_aff mpa) const
+isl::checked::multi_val multi_val::scale_down(long v) const
 {
-  auto res = isl_map_lex_gt_at_multi_pw_aff(copy(), mpa.release());
-  return manage(res);
+  return this->scale_down(isl::checked::val(ctx(), v));
 }
 
-isl::checked::map map::lex_le_at(isl::checked::multi_pw_aff mpa) const
+isl::checked::multi_val multi_val::set_at(int pos, isl::checked::val el) const
 {
-  auto res = isl_map_lex_le_at_multi_pw_aff(copy(), mpa.release());
+  auto res = isl_multi_val_set_at(copy(), pos, el.release());
   return manage(res);
 }
 
-isl::checked::map map::lex_lt_at(isl::checked::multi_pw_aff mpa) const
+isl::checked::multi_val multi_val::set_at(int pos, long el) const
 {
-  auto res = isl_map_lex_lt_at_multi_pw_aff(copy(), mpa.release());
-  return manage(res);
+  return this->set_at(pos, isl::checked::val(ctx(), el));
 }
 
-isl::checked::map map::lexmax() const
+isl::checked::multi_val multi_val::set_range_tuple(isl::checked::id id) const
 {
-  auto res = isl_map_lexmax(copy());
+  auto res = isl_multi_val_set_range_tuple_id(copy(), id.release());
   return manage(res);
 }
 
-isl::checked::pw_multi_aff map::lexmax_pw_multi_aff() const
+isl::checked::multi_val multi_val::set_range_tuple(const std::string &id) const
 {
-  auto res = isl_map_lexmax_pw_multi_aff(copy());
-  return manage(res);
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
 }
 
-isl::checked::map map::lexmin() const
+class size multi_val::size() const
 {
-  auto res = isl_map_lexmin(copy());
+  auto res = isl_multi_val_size(get());
   return manage(res);
 }
 
-isl::checked::pw_multi_aff map::lexmin_pw_multi_aff() const
+isl::checked::space multi_val::space() const
 {
-  auto res = isl_map_lexmin_pw_multi_aff(copy());
+  auto res = isl_multi_val_get_space(get());
   return manage(res);
 }
 
-isl::checked::map map::lower_bound(isl::checked::multi_pw_aff lower) const
+isl::checked::space multi_val::get_space() const
 {
-  auto res = isl_map_lower_bound_multi_pw_aff(copy(), lower.release());
-  return manage(res);
+  return space();
 }
 
-isl::checked::multi_pw_aff map::max_multi_pw_aff() const
+isl::checked::multi_val multi_val::sub(isl::checked::multi_val multi2) const
 {
-  auto res = isl_map_max_multi_pw_aff(copy());
+  auto res = isl_multi_val_sub(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::multi_pw_aff map::min_multi_pw_aff() const
+isl::checked::multi_val multi_val::zero(isl::checked::space space)
 {
-  auto res = isl_map_min_multi_pw_aff(copy());
+  auto res = isl_multi_val_zero(space.release());
   return manage(res);
 }
 
-isl::checked::basic_map map::polyhedral_hull() const
+inline std::ostream &operator<<(std::ostream &os, const multi_val &obj)
 {
-  auto res = isl_map_polyhedral_hull(copy());
-  return manage(res);
+  char *str = isl_multi_val_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
 }
 
-isl::checked::map map::preimage_domain(isl::checked::multi_aff ma) const
-{
-  auto res = isl_map_preimage_domain_multi_aff(copy(), ma.release());
-  return manage(res);
+// implementations for isl::point
+point manage(__isl_take isl_point *ptr) {
+  return point(ptr);
+}
+point manage_copy(__isl_keep isl_point *ptr) {
+  ptr = isl_point_copy(ptr);
+  return point(ptr);
 }
 
-isl::checked::map map::preimage_domain(isl::checked::multi_pw_aff mpa) const
+point::point()
+    : ptr(nullptr) {}
+
+point::point(const point &obj)
+    : ptr(nullptr)
 {
-  auto res = isl_map_preimage_domain_multi_pw_aff(copy(), mpa.release());
-  return manage(res);
+  ptr = obj.copy();
 }
 
-isl::checked::map map::preimage_domain(isl::checked::pw_multi_aff pma) const
-{
-  auto res = isl_map_preimage_domain_pw_multi_aff(copy(), pma.release());
-  return manage(res);
+point::point(__isl_take isl_point *ptr)
+    : ptr(ptr) {}
+
+point &point::operator=(point obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
 }
 
-isl::checked::map map::preimage_range(isl::checked::multi_aff ma) const
-{
-  auto res = isl_map_preimage_range_multi_aff(copy(), ma.release());
-  return manage(res);
+point::~point() {
+  if (ptr)
+    isl_point_free(ptr);
 }
 
-isl::checked::map map::preimage_range(isl::checked::pw_multi_aff pma) const
-{
-  auto res = isl_map_preimage_range_pw_multi_aff(copy(), pma.release());
-  return manage(res);
+__isl_give isl_point *point::copy() const & {
+  return isl_point_copy(ptr);
 }
 
-isl::checked::map map::product(isl::checked::map map2) const
-{
-  auto res = isl_map_product(copy(), map2.release());
-  return manage(res);
+__isl_keep isl_point *point::get() const {
+  return ptr;
 }
 
-isl::checked::map map::project_out_all_params() const
-{
-  auto res = isl_map_project_out_all_params(copy());
-  return manage(res);
+__isl_give isl_point *point::release() {
+  isl_point *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
 }
 
-isl::checked::set map::range() const
-{
-  auto res = isl_map_range(copy());
-  return manage(res);
+bool point::is_null() const {
+  return ptr == nullptr;
 }
 
-isl::checked::map map::range_factor_domain() const
-{
-  auto res = isl_map_range_factor_domain(copy());
-  return manage(res);
+isl::checked::ctx point::ctx() const {
+  return isl::checked::ctx(isl_point_get_ctx(ptr));
 }
 
-isl::checked::map map::range_factor_range() const
+isl::checked::basic_set point::affine_hull() const
 {
-  auto res = isl_map_range_factor_range(copy());
-  return manage(res);
+  return isl::checked::basic_set(*this).affine_hull();
 }
 
-isl::checked::map map::range_product(isl::checked::map map2) const
+isl::checked::basic_set point::apply(const isl::checked::basic_map &bmap) const
 {
-  auto res = isl_map_range_product(copy(), map2.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).apply(bmap);
 }
 
-isl::checked::map map::range_reverse() const
+isl::checked::set point::apply(const isl::checked::map &map) const
 {
-  auto res = isl_map_range_reverse(copy());
-  return manage(res);
+  return isl::checked::basic_set(*this).apply(map);
 }
 
-isl::checked::map map::reverse() const
+isl::checked::union_set point::apply(const isl::checked::union_map &umap) const
 {
-  auto res = isl_map_reverse(copy());
-  return manage(res);
+  return isl::checked::basic_set(*this).apply(umap);
 }
 
-isl::checked::basic_map map::sample() const
+isl::checked::pw_multi_aff point::as_pw_multi_aff() const
 {
-  auto res = isl_map_sample(copy());
-  return manage(res);
+  return isl::checked::basic_set(*this).as_pw_multi_aff();
 }
 
-isl::checked::map map::subtract(isl::checked::map map2) const
+isl::checked::set point::as_set() const
 {
-  auto res = isl_map_subtract(copy(), map2.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).as_set();
 }
 
-isl::checked::map map::uncurry() const
+isl::checked::set point::bind(const isl::checked::multi_id &tuple) const
 {
-  auto res = isl_map_uncurry(copy());
-  return manage(res);
+  return isl::checked::basic_set(*this).bind(tuple);
 }
 
-isl::checked::map map::unite(isl::checked::map map2) const
+isl::checked::set point::coalesce() const
 {
-  auto res = isl_map_union(copy(), map2.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).coalesce();
 }
 
-isl::checked::map map::universe(isl::checked::space space)
+isl::checked::set point::complement() const
 {
-  auto res = isl_map_universe(space.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).complement();
 }
 
-isl::checked::basic_map map::unshifted_simple_hull() const
+isl::checked::union_set point::compute_divs() const
 {
-  auto res = isl_map_unshifted_simple_hull(copy());
-  return manage(res);
+  return isl::checked::basic_set(*this).compute_divs();
 }
 
-isl::checked::map map::upper_bound(isl::checked::multi_pw_aff upper) const
+isl::checked::basic_set point::detect_equalities() const
 {
-  auto res = isl_map_upper_bound_multi_pw_aff(copy(), upper.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).detect_equalities();
 }
 
-isl::checked::set map::wrap() const
+isl::checked::val point::dim_max_val(int pos) const
 {
-  auto res = isl_map_wrap(copy());
-  return manage(res);
+  return isl::checked::basic_set(*this).dim_max_val(pos);
 }
 
-isl::checked::map map::zip() const
+isl::checked::val point::dim_min_val(int pos) const
 {
-  auto res = isl_map_zip(copy());
-  return manage(res);
+  return isl::checked::basic_set(*this).dim_min_val(pos);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const map &obj)
+boolean point::every_set(const std::function<boolean(isl::checked::set)> &test) const
 {
-  char *str = isl_map_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);
-}
-multi_aff manage_copy(__isl_keep isl_multi_aff *ptr) {
-  ptr = isl_multi_aff_copy(ptr);
-  return multi_aff(ptr);
+  return isl::checked::basic_set(*this).every_set(test);
 }
 
-multi_aff::multi_aff()
-    : ptr(nullptr) {}
-
-multi_aff::multi_aff(const multi_aff &obj)
-    : ptr(nullptr)
+isl::checked::set point::extract_set(const isl::checked::space &space) const
 {
-  ptr = obj.copy();
+  return isl::checked::basic_set(*this).extract_set(space);
 }
 
-multi_aff::multi_aff(__isl_take isl_multi_aff *ptr)
-    : ptr(ptr) {}
-
-multi_aff::multi_aff(isl::checked::aff aff)
+isl::checked::basic_set point::flatten() const
 {
-  auto res = isl_multi_aff_from_aff(aff.release());
-  ptr = res;
+  return isl::checked::basic_set(*this).flatten();
 }
 
-multi_aff::multi_aff(isl::checked::space space, isl::checked::aff_list list)
+stat point::foreach_basic_set(const std::function<stat(isl::checked::basic_set)> &fn) const
 {
-  auto res = isl_multi_aff_from_aff_list(space.release(), list.release());
-  ptr = res;
+  return isl::checked::basic_set(*this).foreach_basic_set(fn);
 }
 
-multi_aff::multi_aff(isl::checked::ctx ctx, const std::string &str)
+stat point::foreach_point(const std::function<stat(isl::checked::point)> &fn) const
 {
-  auto res = isl_multi_aff_read_from_str(ctx.release(), str.c_str());
-  ptr = res;
+  return isl::checked::basic_set(*this).foreach_point(fn);
 }
 
-multi_aff &multi_aff::operator=(multi_aff obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+stat point::foreach_set(const std::function<stat(isl::checked::set)> &fn) const
+{
+  return isl::checked::basic_set(*this).foreach_set(fn);
 }
 
-multi_aff::~multi_aff() {
-  if (ptr)
-    isl_multi_aff_free(ptr);
+isl::checked::basic_set point::gist(const isl::checked::basic_set &context) const
+{
+  return isl::checked::basic_set(*this).gist(context);
 }
 
-__isl_give isl_multi_aff *multi_aff::copy() const & {
-  return isl_multi_aff_copy(ptr);
+isl::checked::set point::gist(const isl::checked::set &context) const
+{
+  return isl::checked::basic_set(*this).gist(context);
 }
 
-__isl_keep isl_multi_aff *multi_aff::get() const {
-  return ptr;
+isl::checked::union_set point::gist(const isl::checked::union_set &context) const
+{
+  return isl::checked::basic_set(*this).gist(context);
 }
 
-__isl_give isl_multi_aff *multi_aff::release() {
-  isl_multi_aff *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+isl::checked::union_set point::gist_params(const isl::checked::set &set) const
+{
+  return isl::checked::basic_set(*this).gist_params(set);
 }
 
-bool multi_aff::is_null() const {
-  return ptr == nullptr;
+isl::checked::map point::identity() const
+{
+  return isl::checked::basic_set(*this).identity();
 }
 
-isl::checked::ctx multi_aff::ctx() const {
-  return isl::checked::ctx(isl_multi_aff_get_ctx(ptr));
+isl::checked::pw_aff point::indicator_function() const
+{
+  return isl::checked::basic_set(*this).indicator_function();
 }
 
-isl::checked::multi_aff multi_aff::add(isl::checked::multi_aff multi2) const
+isl::checked::map point::insert_domain(const isl::checked::space &domain) const
 {
-  auto res = isl_multi_aff_add(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).insert_domain(domain);
 }
 
-isl::checked::multi_aff multi_aff::add_constant(isl::checked::multi_val mv) const
+isl::checked::basic_set point::intersect(const isl::checked::basic_set &bset2) const
 {
-  auto res = isl_multi_aff_add_constant_multi_val(copy(), mv.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).intersect(bset2);
 }
 
-isl::checked::multi_aff multi_aff::add_constant(isl::checked::val v) const
+isl::checked::set point::intersect(const isl::checked::set &set2) const
 {
-  auto res = isl_multi_aff_add_constant_val(copy(), v.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).intersect(set2);
 }
 
-isl::checked::multi_aff multi_aff::add_constant(long v) const
+isl::checked::union_set point::intersect(const isl::checked::union_set &uset2) const
 {
-  return this->add_constant(isl::checked::val(ctx(), v));
+  return isl::checked::basic_set(*this).intersect(uset2);
 }
 
-isl::checked::basic_set multi_aff::bind(isl::checked::multi_id tuple) const
+isl::checked::basic_set point::intersect_params(const isl::checked::basic_set &bset2) const
 {
-  auto res = isl_multi_aff_bind(copy(), tuple.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).intersect_params(bset2);
 }
 
-isl::checked::multi_aff multi_aff::bind_domain(isl::checked::multi_id tuple) const
+isl::checked::set point::intersect_params(const isl::checked::set &params) const
 {
-  auto res = isl_multi_aff_bind_domain(copy(), tuple.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).intersect_params(params);
 }
 
-isl::checked::multi_aff multi_aff::bind_domain_wrapped_domain(isl::checked::multi_id tuple) const
+boolean point::involves_locals() const
 {
-  auto res = isl_multi_aff_bind_domain_wrapped_domain(copy(), tuple.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).involves_locals();
 }
 
-isl::checked::multi_aff multi_aff::domain_map(isl::checked::space space)
+boolean point::is_disjoint(const isl::checked::set &set2) const
 {
-  auto res = isl_multi_aff_domain_map(space.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).is_disjoint(set2);
 }
 
-isl::checked::multi_aff multi_aff::flat_range_product(isl::checked::multi_aff multi2) const
+boolean point::is_disjoint(const isl::checked::union_set &uset2) const
 {
-  auto res = isl_multi_aff_flat_range_product(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).is_disjoint(uset2);
 }
 
-isl::checked::multi_aff multi_aff::floor() const
+boolean point::is_empty() const
 {
-  auto res = isl_multi_aff_floor(copy());
-  return manage(res);
+  return isl::checked::basic_set(*this).is_empty();
 }
 
-isl::checked::aff multi_aff::at(int pos) const
+boolean point::is_equal(const isl::checked::basic_set &bset2) const
 {
-  auto res = isl_multi_aff_get_at(get(), pos);
-  return manage(res);
+  return isl::checked::basic_set(*this).is_equal(bset2);
 }
 
-isl::checked::aff multi_aff::get_at(int pos) const
+boolean point::is_equal(const isl::checked::set &set2) const
 {
-  return at(pos);
+  return isl::checked::basic_set(*this).is_equal(set2);
 }
 
-isl::checked::multi_val multi_aff::constant_multi_val() const
+boolean point::is_equal(const isl::checked::union_set &uset2) const
 {
-  auto res = isl_multi_aff_get_constant_multi_val(get());
-  return manage(res);
+  return isl::checked::basic_set(*this).is_equal(uset2);
 }
 
-isl::checked::multi_val multi_aff::get_constant_multi_val() const
+boolean point::is_singleton() const
 {
-  return constant_multi_val();
+  return isl::checked::basic_set(*this).is_singleton();
 }
 
-isl::checked::aff_list multi_aff::list() const
+boolean point::is_strict_subset(const isl::checked::set &set2) const
 {
-  auto res = isl_multi_aff_get_list(get());
-  return manage(res);
+  return isl::checked::basic_set(*this).is_strict_subset(set2);
 }
 
-isl::checked::aff_list multi_aff::get_list() const
+boolean point::is_strict_subset(const isl::checked::union_set &uset2) const
 {
-  return list();
+  return isl::checked::basic_set(*this).is_strict_subset(uset2);
 }
 
-isl::checked::space multi_aff::space() const
+boolean point::is_subset(const isl::checked::basic_set &bset2) const
 {
-  auto res = isl_multi_aff_get_space(get());
-  return manage(res);
+  return isl::checked::basic_set(*this).is_subset(bset2);
 }
 
-isl::checked::space multi_aff::get_space() const
+boolean point::is_subset(const isl::checked::set &set2) const
 {
-  return space();
+  return isl::checked::basic_set(*this).is_subset(set2);
 }
 
-isl::checked::multi_aff multi_aff::gist(isl::checked::set context) const
+boolean point::is_subset(const isl::checked::union_set &uset2) const
 {
-  auto res = isl_multi_aff_gist(copy(), context.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).is_subset(uset2);
 }
 
-isl::checked::multi_aff multi_aff::identity() const
+boolean point::is_wrapping() const
 {
-  auto res = isl_multi_aff_identity_multi_aff(copy());
-  return manage(res);
+  return isl::checked::basic_set(*this).is_wrapping();
 }
 
-isl::checked::multi_aff multi_aff::identity_on_domain(isl::checked::space space)
+boolean point::isa_set() const
 {
-  auto res = isl_multi_aff_identity_on_domain_space(space.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).isa_set();
 }
 
-isl::checked::multi_aff multi_aff::insert_domain(isl::checked::space domain) const
+isl::checked::set point::lexmax() const
 {
-  auto res = isl_multi_aff_insert_domain(copy(), domain.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).lexmax();
 }
 
-boolean multi_aff::involves_locals() const
+isl::checked::pw_multi_aff point::lexmax_pw_multi_aff() const
 {
-  auto res = isl_multi_aff_involves_locals(get());
-  return manage(res);
+  return isl::checked::basic_set(*this).lexmax_pw_multi_aff();
 }
 
-boolean multi_aff::involves_nan() const
+isl::checked::set point::lexmin() const
 {
-  auto res = isl_multi_aff_involves_nan(get());
-  return manage(res);
+  return isl::checked::basic_set(*this).lexmin();
 }
 
-isl::checked::multi_aff multi_aff::neg() const
+isl::checked::pw_multi_aff point::lexmin_pw_multi_aff() const
 {
-  auto res = isl_multi_aff_neg(copy());
-  return manage(res);
+  return isl::checked::basic_set(*this).lexmin_pw_multi_aff();
 }
 
-boolean multi_aff::plain_is_equal(const isl::checked::multi_aff &multi2) const
+isl::checked::set point::lower_bound(const isl::checked::multi_pw_aff &lower) const
 {
-  auto res = isl_multi_aff_plain_is_equal(get(), multi2.get());
-  return manage(res);
+  return isl::checked::basic_set(*this).lower_bound(lower);
 }
 
-isl::checked::multi_aff multi_aff::product(isl::checked::multi_aff multi2) const
+isl::checked::set point::lower_bound(const isl::checked::multi_val &lower) const
 {
-  auto res = isl_multi_aff_product(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).lower_bound(lower);
 }
 
-isl::checked::multi_aff multi_aff::pullback(isl::checked::multi_aff ma2) const
+isl::checked::multi_pw_aff point::max_multi_pw_aff() const
 {
-  auto res = isl_multi_aff_pullback_multi_aff(copy(), ma2.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).max_multi_pw_aff();
 }
 
-isl::checked::multi_aff multi_aff::range_map(isl::checked::space space)
+isl::checked::val point::max_val(const isl::checked::aff &obj) const
 {
-  auto res = isl_multi_aff_range_map(space.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).max_val(obj);
 }
 
-isl::checked::multi_aff multi_aff::range_product(isl::checked::multi_aff multi2) const
+isl::checked::multi_pw_aff point::min_multi_pw_aff() const
 {
-  auto res = isl_multi_aff_range_product(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).min_multi_pw_aff();
 }
 
-isl::checked::multi_aff multi_aff::scale(isl::checked::multi_val mv) const
+isl::checked::val point::min_val(const isl::checked::aff &obj) const
 {
-  auto res = isl_multi_aff_scale_multi_val(copy(), mv.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).min_val(obj);
 }
 
-isl::checked::multi_aff multi_aff::scale(isl::checked::val v) const
+isl::checked::multi_val point::multi_val() const
 {
-  auto res = isl_multi_aff_scale_val(copy(), v.release());
+  auto res = isl_point_get_multi_val(get());
   return manage(res);
 }
 
-isl::checked::multi_aff multi_aff::scale(long v) const
+isl::checked::multi_val point::get_multi_val() const
 {
-  return this->scale(isl::checked::val(ctx(), v));
+  return multi_val();
 }
 
-isl::checked::multi_aff multi_aff::scale_down(isl::checked::multi_val mv) const
+isl::checked::basic_set point::params() const
 {
-  auto res = isl_multi_aff_scale_down_multi_val(copy(), mv.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).params();
 }
 
-isl::checked::multi_aff multi_aff::scale_down(isl::checked::val v) const
+isl::checked::multi_val point::plain_multi_val_if_fixed() const
 {
-  auto res = isl_multi_aff_scale_down_val(copy(), v.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).plain_multi_val_if_fixed();
 }
 
-isl::checked::multi_aff multi_aff::scale_down(long v) const
+isl::checked::basic_set point::polyhedral_hull() const
 {
-  return this->scale_down(isl::checked::val(ctx(), v));
+  return isl::checked::basic_set(*this).polyhedral_hull();
 }
 
-isl::checked::multi_aff multi_aff::set_at(int pos, isl::checked::aff el) const
+isl::checked::set point::preimage(const isl::checked::multi_aff &ma) const
 {
-  auto res = isl_multi_aff_set_at(copy(), pos, el.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).preimage(ma);
 }
 
-class size multi_aff::size() const
+isl::checked::set point::preimage(const isl::checked::multi_pw_aff &mpa) const
 {
-  auto res = isl_multi_aff_size(get());
-  return manage(res);
+  return isl::checked::basic_set(*this).preimage(mpa);
 }
 
-isl::checked::multi_aff multi_aff::sub(isl::checked::multi_aff multi2) const
+isl::checked::set point::preimage(const isl::checked::pw_multi_aff &pma) const
 {
-  auto res = isl_multi_aff_sub(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).preimage(pma);
 }
 
-isl::checked::multi_aff multi_aff::unbind_params_insert_domain(isl::checked::multi_id domain) const
+isl::checked::union_set point::preimage(const isl::checked::union_pw_multi_aff &upma) const
 {
-  auto res = isl_multi_aff_unbind_params_insert_domain(copy(), domain.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).preimage(upma);
 }
 
-isl::checked::multi_aff multi_aff::zero(isl::checked::space space)
+isl::checked::set point::product(const isl::checked::set &set2) const
 {
-  auto res = isl_multi_aff_zero(space.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).product(set2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const multi_aff &obj)
+isl::checked::set point::project_out_all_params() const
 {
-  char *str = isl_multi_aff_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::basic_set(*this).project_out_all_params();
 }
 
-// implementations for isl::multi_id
-multi_id manage(__isl_take isl_multi_id *ptr) {
-  return multi_id(ptr);
-}
-multi_id manage_copy(__isl_keep isl_multi_id *ptr) {
-  ptr = isl_multi_id_copy(ptr);
-  return multi_id(ptr);
+isl::checked::set point::project_out_param(const isl::checked::id &id) const
+{
+  return isl::checked::basic_set(*this).project_out_param(id);
 }
 
-multi_id::multi_id()
-    : ptr(nullptr) {}
-
-multi_id::multi_id(const multi_id &obj)
-    : ptr(nullptr)
+isl::checked::set point::project_out_param(const std::string &id) const
 {
-  ptr = obj.copy();
+  return this->project_out_param(isl::checked::id(ctx(), id));
 }
 
-multi_id::multi_id(__isl_take isl_multi_id *ptr)
-    : ptr(ptr) {}
+isl::checked::set point::project_out_param(const isl::checked::id_list &list) const
+{
+  return isl::checked::basic_set(*this).project_out_param(list);
+}
 
-multi_id::multi_id(isl::checked::space space, isl::checked::id_list list)
+isl::checked::pw_multi_aff point::pw_multi_aff_on_domain(const isl::checked::multi_val &mv) const
 {
-  auto res = isl_multi_id_from_id_list(space.release(), list.release());
-  ptr = res;
+  return isl::checked::basic_set(*this).pw_multi_aff_on_domain(mv);
 }
 
-multi_id::multi_id(isl::checked::ctx ctx, const std::string &str)
+isl::checked::basic_set point::sample() const
 {
-  auto res = isl_multi_id_read_from_str(ctx.release(), str.c_str());
-  ptr = res;
+  return isl::checked::basic_set(*this).sample();
 }
 
-multi_id &multi_id::operator=(multi_id obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::checked::point point::sample_point() const
+{
+  return isl::checked::basic_set(*this).sample_point();
 }
 
-multi_id::~multi_id() {
-  if (ptr)
-    isl_multi_id_free(ptr);
+isl::checked::fixed_box point::simple_fixed_box_hull() const
+{
+  return isl::checked::basic_set(*this).simple_fixed_box_hull();
 }
 
-__isl_give isl_multi_id *multi_id::copy() const & {
-  return isl_multi_id_copy(ptr);
+isl::checked::space point::space() const
+{
+  return isl::checked::basic_set(*this).space();
 }
 
-__isl_keep isl_multi_id *multi_id::get() const {
-  return ptr;
+isl::checked::val point::stride(int pos) const
+{
+  return isl::checked::basic_set(*this).stride(pos);
 }
 
-__isl_give isl_multi_id *multi_id::release() {
-  isl_multi_id *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+isl::checked::set point::subtract(const isl::checked::set &set2) const
+{
+  return isl::checked::basic_set(*this).subtract(set2);
 }
 
-bool multi_id::is_null() const {
-  return ptr == nullptr;
+isl::checked::union_set point::subtract(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::basic_set(*this).subtract(uset2);
 }
 
-isl::checked::ctx multi_id::ctx() const {
-  return isl::checked::ctx(isl_multi_id_get_ctx(ptr));
+isl::checked::union_set_list point::to_list() const
+{
+  return isl::checked::basic_set(*this).to_list();
 }
 
-isl::checked::multi_id multi_id::flat_range_product(isl::checked::multi_id multi2) const
+isl::checked::set point::to_set() const
 {
-  auto res = isl_multi_id_flat_range_product(copy(), multi2.release());
+  auto res = isl_point_to_set(copy());
   return manage(res);
 }
 
-isl::checked::id multi_id::at(int pos) const
+isl::checked::union_set point::to_union_set() const
 {
-  auto res = isl_multi_id_get_at(get(), pos);
-  return manage(res);
+  return isl::checked::basic_set(*this).to_union_set();
 }
 
-isl::checked::id multi_id::get_at(int pos) const
+isl::checked::map point::translation() const
 {
-  return at(pos);
+  return isl::checked::basic_set(*this).translation();
 }
 
-isl::checked::id_list multi_id::list() const
+class size point::tuple_dim() const
 {
-  auto res = isl_multi_id_get_list(get());
-  return manage(res);
+  return isl::checked::basic_set(*this).tuple_dim();
 }
 
-isl::checked::id_list multi_id::get_list() const
+isl::checked::set point::unbind_params(const isl::checked::multi_id &tuple) const
 {
-  return list();
+  return isl::checked::basic_set(*this).unbind_params(tuple);
 }
 
-isl::checked::space multi_id::space() const
+isl::checked::map point::unbind_params_insert_domain(const isl::checked::multi_id &domain) const
 {
-  auto res = isl_multi_id_get_space(get());
-  return manage(res);
+  return isl::checked::basic_set(*this).unbind_params_insert_domain(domain);
 }
 
-isl::checked::space multi_id::get_space() const
+isl::checked::set point::unite(const isl::checked::basic_set &bset2) const
 {
-  return space();
+  return isl::checked::basic_set(*this).unite(bset2);
 }
 
-boolean multi_id::plain_is_equal(const isl::checked::multi_id &multi2) const
+isl::checked::set point::unite(const isl::checked::set &set2) const
 {
-  auto res = isl_multi_id_plain_is_equal(get(), multi2.get());
-  return manage(res);
+  return isl::checked::basic_set(*this).unite(set2);
 }
 
-isl::checked::multi_id multi_id::range_product(isl::checked::multi_id multi2) const
+isl::checked::union_set point::unite(const isl::checked::union_set &uset2) const
 {
-  auto res = isl_multi_id_range_product(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).unite(uset2);
 }
 
-isl::checked::multi_id multi_id::set_at(int pos, isl::checked::id el) const
+isl::checked::basic_set point::unshifted_simple_hull() const
 {
-  auto res = isl_multi_id_set_at(copy(), pos, el.release());
-  return manage(res);
+  return isl::checked::basic_set(*this).unshifted_simple_hull();
 }
 
-isl::checked::multi_id multi_id::set_at(int pos, const std::string &el) const
+isl::checked::map point::unwrap() const
 {
-  return this->set_at(pos, isl::checked::id(ctx(), el));
+  return isl::checked::basic_set(*this).unwrap();
 }
 
-class size multi_id::size() const
+isl::checked::set point::upper_bound(const isl::checked::multi_pw_aff &upper) const
 {
-  auto res = isl_multi_id_size(get());
-  return manage(res);
+  return isl::checked::basic_set(*this).upper_bound(upper);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const multi_id &obj)
+isl::checked::set point::upper_bound(const isl::checked::multi_val &upper) const
 {
-  char *str = isl_multi_id_to_str(obj.get());
+  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());
   if (!str) {
     os.setstate(std::ios_base::badbit);
     return os;
@@ -7153,887 +12572,812 @@ inline std::ostream &operator<<(std::ostream &os, const multi_id &obj)
   return os;
 }
 
-// implementations for isl::multi_pw_aff
-multi_pw_aff manage(__isl_take isl_multi_pw_aff *ptr) {
-  return multi_pw_aff(ptr);
+// implementations for isl::pw_aff
+pw_aff manage(__isl_take isl_pw_aff *ptr) {
+  return pw_aff(ptr);
 }
-multi_pw_aff manage_copy(__isl_keep isl_multi_pw_aff *ptr) {
-  ptr = isl_multi_pw_aff_copy(ptr);
-  return multi_pw_aff(ptr);
+pw_aff manage_copy(__isl_keep isl_pw_aff *ptr) {
+  ptr = isl_pw_aff_copy(ptr);
+  return pw_aff(ptr);
 }
 
-multi_pw_aff::multi_pw_aff()
+pw_aff::pw_aff()
     : ptr(nullptr) {}
 
-multi_pw_aff::multi_pw_aff(const multi_pw_aff &obj)
+pw_aff::pw_aff(const pw_aff &obj)
     : ptr(nullptr)
 {
   ptr = obj.copy();
 }
 
-multi_pw_aff::multi_pw_aff(__isl_take isl_multi_pw_aff *ptr)
+pw_aff::pw_aff(__isl_take isl_pw_aff *ptr)
     : ptr(ptr) {}
 
-multi_pw_aff::multi_pw_aff(isl::checked::aff aff)
-{
-  auto res = isl_multi_pw_aff_from_aff(aff.release());
-  ptr = res;
-}
-
-multi_pw_aff::multi_pw_aff(isl::checked::multi_aff ma)
-{
-  auto res = isl_multi_pw_aff_from_multi_aff(ma.release());
-  ptr = res;
-}
-
-multi_pw_aff::multi_pw_aff(isl::checked::pw_aff pa)
-{
-  auto res = isl_multi_pw_aff_from_pw_aff(pa.release());
-  ptr = res;
-}
-
-multi_pw_aff::multi_pw_aff(isl::checked::space space, isl::checked::pw_aff_list list)
-{
-  auto res = isl_multi_pw_aff_from_pw_aff_list(space.release(), list.release());
-  ptr = res;
-}
-
-multi_pw_aff::multi_pw_aff(isl::checked::pw_multi_aff pma)
+pw_aff::pw_aff(isl::checked::aff aff)
 {
-  auto res = isl_multi_pw_aff_from_pw_multi_aff(pma.release());
+  auto res = isl_pw_aff_from_aff(aff.release());
   ptr = res;
 }
 
-multi_pw_aff::multi_pw_aff(isl::checked::ctx ctx, const std::string &str)
+pw_aff::pw_aff(isl::checked::ctx ctx, const std::string &str)
 {
-  auto res = isl_multi_pw_aff_read_from_str(ctx.release(), str.c_str());
+  auto res = isl_pw_aff_read_from_str(ctx.release(), str.c_str());
   ptr = res;
 }
 
-multi_pw_aff &multi_pw_aff::operator=(multi_pw_aff obj) {
+pw_aff &pw_aff::operator=(pw_aff obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-multi_pw_aff::~multi_pw_aff() {
+pw_aff::~pw_aff() {
   if (ptr)
-    isl_multi_pw_aff_free(ptr);
+    isl_pw_aff_free(ptr);
 }
 
-__isl_give isl_multi_pw_aff *multi_pw_aff::copy() const & {
-  return isl_multi_pw_aff_copy(ptr);
+__isl_give isl_pw_aff *pw_aff::copy() const & {
+  return isl_pw_aff_copy(ptr);
 }
 
-__isl_keep isl_multi_pw_aff *multi_pw_aff::get() const {
+__isl_keep isl_pw_aff *pw_aff::get() const {
   return ptr;
 }
 
-__isl_give isl_multi_pw_aff *multi_pw_aff::release() {
-  isl_multi_pw_aff *tmp = ptr;
+__isl_give isl_pw_aff *pw_aff::release() {
+  isl_pw_aff *tmp = ptr;
   ptr = nullptr;
   return tmp;
 }
 
-bool multi_pw_aff::is_null() const {
+bool pw_aff::is_null() const {
   return ptr == nullptr;
 }
 
-isl::checked::ctx multi_pw_aff::ctx() const {
-  return isl::checked::ctx(isl_multi_pw_aff_get_ctx(ptr));
+isl::checked::ctx pw_aff::ctx() const {
+  return isl::checked::ctx(isl_pw_aff_get_ctx(ptr));
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::add(isl::checked::multi_pw_aff multi2) const
+isl::checked::multi_pw_aff pw_aff::add(const isl::checked::multi_pw_aff &multi2) const
 {
-  auto res = isl_multi_pw_aff_add(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).add(multi2);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::add_constant(isl::checked::multi_val mv) const
+isl::checked::multi_union_pw_aff pw_aff::add(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  auto res = isl_multi_pw_aff_add_constant_multi_val(copy(), mv.release());
+  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::multi_pw_aff multi_pw_aff::add_constant(isl::checked::val v) const
+isl::checked::pw_multi_aff pw_aff::add(const isl::checked::pw_multi_aff &pma2) const
 {
-  auto res = isl_multi_pw_aff_add_constant_val(copy(), v.release());
+  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());
   return manage(res);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::add_constant(long v) const
+isl::checked::pw_aff pw_aff::add_constant(long v) const
 {
   return this->add_constant(isl::checked::val(ctx(), v));
 }
 
-isl::checked::set multi_pw_aff::bind(isl::checked::multi_id tuple) const
+isl::checked::pw_multi_aff pw_aff::add_constant(const isl::checked::multi_val &mv) const
 {
-  auto res = isl_multi_pw_aff_bind(copy(), tuple.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).add_constant(mv);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::bind_domain(isl::checked::multi_id tuple) const
+isl::checked::union_pw_multi_aff pw_aff::apply(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_multi_pw_aff_bind_domain(copy(), tuple.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).apply(upma2);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::bind_domain_wrapped_domain(isl::checked::multi_id tuple) const
+isl::checked::aff pw_aff::as_aff() const
 {
-  auto res = isl_multi_pw_aff_bind_domain_wrapped_domain(copy(), tuple.release());
+  auto res = isl_pw_aff_as_aff(copy());
   return manage(res);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::coalesce() const
+isl::checked::map pw_aff::as_map() const
 {
-  auto res = isl_multi_pw_aff_coalesce(copy());
+  auto res = isl_pw_aff_as_map(copy());
   return manage(res);
 }
 
-isl::checked::set multi_pw_aff::domain() const
+isl::checked::multi_aff pw_aff::as_multi_aff() const
 {
-  auto res = isl_multi_pw_aff_domain(copy());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).as_multi_aff();
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(isl::checked::multi_pw_aff multi2) const
+isl::checked::multi_union_pw_aff pw_aff::as_multi_union_pw_aff() const
 {
-  auto res = isl_multi_pw_aff_flat_range_product(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).as_multi_union_pw_aff();
 }
 
-isl::checked::pw_aff multi_pw_aff::at(int pos) const
+isl::checked::pw_multi_aff pw_aff::as_pw_multi_aff() const
 {
-  auto res = isl_multi_pw_aff_get_at(get(), pos);
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).as_pw_multi_aff();
 }
 
-isl::checked::pw_aff multi_pw_aff::get_at(int pos) const
+isl::checked::set pw_aff::as_set() const
 {
-  return at(pos);
+  return isl::checked::pw_multi_aff(*this).as_set();
 }
 
-isl::checked::pw_aff_list multi_pw_aff::list() const
+isl::checked::union_map pw_aff::as_union_map() const
 {
-  auto res = isl_multi_pw_aff_get_list(get());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).as_union_map();
 }
 
-isl::checked::pw_aff_list multi_pw_aff::get_list() const
+isl::checked::pw_aff pw_aff::at(int pos) const
 {
-  return list();
+  return isl::checked::pw_multi_aff(*this).at(pos);
 }
 
-isl::checked::space multi_pw_aff::space() const
+isl::checked::set pw_aff::bind(const isl::checked::multi_id &tuple) const
 {
-  auto res = isl_multi_pw_aff_get_space(get());
+  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());
   return manage(res);
 }
 
-isl::checked::space multi_pw_aff::get_space() const
+isl::checked::set pw_aff::bind(const std::string &id) const
 {
-  return space();
+  return this->bind(isl::checked::id(ctx(), id));
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::gist(isl::checked::set set) const
+isl::checked::pw_aff pw_aff::bind_domain(isl::checked::multi_id tuple) const
 {
-  auto res = isl_multi_pw_aff_gist(copy(), set.release());
+  auto res = isl_pw_aff_bind_domain(copy(), tuple.release());
   return manage(res);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::identity() const
+isl::checked::pw_aff pw_aff::bind_domain_wrapped_domain(isl::checked::multi_id tuple) const
 {
-  auto res = isl_multi_pw_aff_identity_multi_pw_aff(copy());
+  auto res = isl_pw_aff_bind_domain_wrapped_domain(copy(), tuple.release());
   return manage(res);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::identity_on_domain(isl::checked::space space)
+isl::checked::pw_aff pw_aff::ceil() const
 {
-  auto res = isl_multi_pw_aff_identity_on_domain_space(space.release());
+  auto res = isl_pw_aff_ceil(copy());
   return manage(res);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::insert_domain(isl::checked::space domain) const
+isl::checked::pw_aff pw_aff::coalesce() const
 {
-  auto res = isl_multi_pw_aff_insert_domain(copy(), domain.release());
+  auto res = isl_pw_aff_coalesce(copy());
   return manage(res);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::intersect_domain(isl::checked::set domain) const
+isl::checked::pw_aff pw_aff::cond(isl::checked::pw_aff pwaff_true, isl::checked::pw_aff pwaff_false) const
 {
-  auto res = isl_multi_pw_aff_intersect_domain(copy(), domain.release());
+  auto res = isl_pw_aff_cond(copy(), pwaff_true.release(), pwaff_false.release());
   return manage(res);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::intersect_params(isl::checked::set set) const
+isl::checked::pw_aff pw_aff::div(isl::checked::pw_aff pa2) const
 {
-  auto res = isl_multi_pw_aff_intersect_params(copy(), set.release());
+  auto res = isl_pw_aff_div(copy(), pa2.release());
   return manage(res);
 }
 
-boolean multi_pw_aff::involves_nan() const
+isl::checked::set pw_aff::domain() const
 {
-  auto res = isl_multi_pw_aff_involves_nan(get());
+  auto res = isl_pw_aff_domain(copy());
   return manage(res);
 }
 
-boolean multi_pw_aff::involves_param(const isl::checked::id &id) const
+isl::checked::set pw_aff::eq_set(isl::checked::pw_aff pwaff2) const
 {
-  auto res = isl_multi_pw_aff_involves_param_id(get(), id.get());
+  auto res = isl_pw_aff_eq_set(copy(), pwaff2.release());
   return manage(res);
 }
 
-boolean multi_pw_aff::involves_param(const std::string &id) const
+isl::checked::val pw_aff::eval(isl::checked::point pnt) const
 {
-  return this->involves_param(isl::checked::id(ctx(), id));
+  auto res = isl_pw_aff_eval(copy(), pnt.release());
+  return manage(res);
 }
 
-boolean multi_pw_aff::involves_param(const isl::checked::id_list &list) const
+isl::checked::pw_multi_aff pw_aff::extract_pw_multi_aff(const isl::checked::space &space) const
 {
-  auto res = isl_multi_pw_aff_involves_param_id_list(get(), list.get());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).extract_pw_multi_aff(space);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::max(isl::checked::multi_pw_aff multi2) const
+isl::checked::multi_pw_aff pw_aff::flat_range_product(const isl::checked::multi_pw_aff &multi2) const
 {
-  auto res = isl_multi_pw_aff_max(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).flat_range_product(multi2);
 }
 
-isl::checked::multi_val multi_pw_aff::max_multi_val() const
+isl::checked::multi_union_pw_aff pw_aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  auto res = isl_multi_pw_aff_max_multi_val(copy());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).flat_range_product(multi2);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::min(isl::checked::multi_pw_aff multi2) const
+isl::checked::pw_multi_aff pw_aff::flat_range_product(const isl::checked::pw_multi_aff &pma2) const
 {
-  auto res = isl_multi_pw_aff_min(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).flat_range_product(pma2);
 }
 
-isl::checked::multi_val multi_pw_aff::min_multi_val() const
+isl::checked::union_pw_multi_aff pw_aff::flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_multi_pw_aff_min_multi_val(copy());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).flat_range_product(upma2);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::neg() const
+isl::checked::pw_aff pw_aff::floor() const
 {
-  auto res = isl_multi_pw_aff_neg(copy());
+  auto res = isl_pw_aff_floor(copy());
   return manage(res);
 }
 
-boolean multi_pw_aff::plain_is_equal(const isl::checked::multi_pw_aff &multi2) const
+stat pw_aff::foreach_piece(const std::function<stat(isl::checked::set, isl::checked::multi_aff)> &fn) const
 {
-  auto res = isl_multi_pw_aff_plain_is_equal(get(), multi2.get());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).foreach_piece(fn);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::product(isl::checked::multi_pw_aff multi2) const
+isl::checked::set pw_aff::ge_set(isl::checked::pw_aff pwaff2) const
 {
-  auto res = isl_multi_pw_aff_product(copy(), multi2.release());
+  auto res = isl_pw_aff_ge_set(copy(), pwaff2.release());
   return manage(res);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::pullback(isl::checked::multi_aff ma) const
+isl::checked::pw_aff pw_aff::gist(isl::checked::set context) const
 {
-  auto res = isl_multi_pw_aff_pullback_multi_aff(copy(), ma.release());
+  auto res = isl_pw_aff_gist(copy(), context.release());
   return manage(res);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::pullback(isl::checked::multi_pw_aff mpa2) const
+isl::checked::union_pw_aff pw_aff::gist(const isl::checked::union_set &context) const
 {
-  auto res = isl_multi_pw_aff_pullback_multi_pw_aff(copy(), mpa2.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).gist(context);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::pullback(isl::checked::pw_multi_aff pma) const
+isl::checked::pw_aff pw_aff::gist(const isl::checked::basic_set &context) const
 {
-  auto res = isl_multi_pw_aff_pullback_pw_multi_aff(copy(), pma.release());
-  return manage(res);
+  return this->gist(isl::checked::set(context));
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::range_product(isl::checked::multi_pw_aff multi2) const
+isl::checked::pw_aff pw_aff::gist(const isl::checked::point &context) const
 {
-  auto res = isl_multi_pw_aff_range_product(copy(), multi2.release());
-  return manage(res);
+  return this->gist(isl::checked::set(context));
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::scale(isl::checked::multi_val mv) const
+isl::checked::set pw_aff::gt_set(isl::checked::pw_aff pwaff2) const
 {
-  auto res = isl_multi_pw_aff_scale_multi_val(copy(), mv.release());
+  auto res = isl_pw_aff_gt_set(copy(), pwaff2.release());
   return manage(res);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::scale(isl::checked::val v) const
+boolean pw_aff::has_range_tuple_id() const
 {
-  auto res = isl_multi_pw_aff_scale_val(copy(), v.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).has_range_tuple_id();
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::scale(long v) const
+isl::checked::multi_pw_aff pw_aff::identity() const
 {
-  return this->scale(isl::checked::val(ctx(), v));
+  return isl::checked::pw_multi_aff(*this).identity();
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::scale_down(isl::checked::multi_val mv) const
+isl::checked::pw_aff pw_aff::insert_domain(isl::checked::space domain) const
 {
-  auto res = isl_multi_pw_aff_scale_down_multi_val(copy(), mv.release());
+  auto res = isl_pw_aff_insert_domain(copy(), domain.release());
   return manage(res);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::scale_down(isl::checked::val v) const
+isl::checked::pw_aff pw_aff::intersect_domain(isl::checked::set set) const
 {
-  auto res = isl_multi_pw_aff_scale_down_val(copy(), v.release());
+  auto res = isl_pw_aff_intersect_domain(copy(), set.release());
   return manage(res);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::scale_down(long v) const
+isl::checked::union_pw_aff pw_aff::intersect_domain(const isl::checked::space &space) const
 {
-  return this->scale_down(isl::checked::val(ctx(), v));
+  return isl::checked::union_pw_aff(*this).intersect_domain(space);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::set_at(int pos, isl::checked::pw_aff el) const
+isl::checked::union_pw_aff pw_aff::intersect_domain(const isl::checked::union_set &uset) const
 {
-  auto res = isl_multi_pw_aff_set_at(copy(), pos, el.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).intersect_domain(uset);
 }
 
-class size multi_pw_aff::size() const
+isl::checked::pw_aff pw_aff::intersect_domain(const isl::checked::basic_set &set) const
 {
-  auto res = isl_multi_pw_aff_size(get());
-  return manage(res);
+  return this->intersect_domain(isl::checked::set(set));
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::sub(isl::checked::multi_pw_aff multi2) const
+isl::checked::pw_aff pw_aff::intersect_domain(const isl::checked::point &set) const
 {
-  auto res = isl_multi_pw_aff_sub(copy(), multi2.release());
-  return manage(res);
+  return this->intersect_domain(isl::checked::set(set));
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::unbind_params_insert_domain(isl::checked::multi_id domain) const
+isl::checked::union_pw_aff pw_aff::intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const
 {
-  auto res = isl_multi_pw_aff_unbind_params_insert_domain(copy(), domain.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).intersect_domain_wrapped_domain(uset);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::union_add(isl::checked::multi_pw_aff mpa2) const
+isl::checked::union_pw_aff pw_aff::intersect_domain_wrapped_range(const isl::checked::union_set &uset) const
 {
-  auto res = isl_multi_pw_aff_union_add(copy(), mpa2.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).intersect_domain_wrapped_range(uset);
 }
 
-isl::checked::multi_pw_aff multi_pw_aff::zero(isl::checked::space space)
+isl::checked::pw_aff pw_aff::intersect_params(isl::checked::set set) const
 {
-  auto res = isl_multi_pw_aff_zero(space.release());
+  auto res = isl_pw_aff_intersect_params(copy(), set.release());
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const multi_pw_aff &obj)
+boolean pw_aff::involves_locals() const
 {
-  char *str = isl_multi_pw_aff_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_multi_aff(*this).involves_locals();
 }
 
-// implementations for isl::multi_union_pw_aff
-multi_union_pw_aff manage(__isl_take isl_multi_union_pw_aff *ptr) {
-  return multi_union_pw_aff(ptr);
-}
-multi_union_pw_aff manage_copy(__isl_keep isl_multi_union_pw_aff *ptr) {
-  ptr = isl_multi_union_pw_aff_copy(ptr);
-  return multi_union_pw_aff(ptr);
+boolean pw_aff::involves_nan() const
+{
+  return isl::checked::multi_pw_aff(*this).involves_nan();
 }
 
-multi_union_pw_aff::multi_union_pw_aff()
-    : ptr(nullptr) {}
-
-multi_union_pw_aff::multi_union_pw_aff(const multi_union_pw_aff &obj)
-    : ptr(nullptr)
+boolean pw_aff::involves_param(const isl::checked::id &id) const
 {
-  ptr = obj.copy();
+  return isl::checked::pw_multi_aff(*this).involves_param(id);
 }
 
-multi_union_pw_aff::multi_union_pw_aff(__isl_take isl_multi_union_pw_aff *ptr)
-    : ptr(ptr) {}
-
-multi_union_pw_aff::multi_union_pw_aff(isl::checked::multi_pw_aff mpa)
+boolean pw_aff::involves_param(const std::string &id) const
 {
-  auto res = isl_multi_union_pw_aff_from_multi_pw_aff(mpa.release());
-  ptr = res;
+  return this->involves_param(isl::checked::id(ctx(), id));
 }
 
-multi_union_pw_aff::multi_union_pw_aff(isl::checked::union_pw_aff upa)
+boolean pw_aff::involves_param(const isl::checked::id_list &list) const
 {
-  auto res = isl_multi_union_pw_aff_from_union_pw_aff(upa.release());
-  ptr = res;
+  return isl::checked::pw_multi_aff(*this).involves_param(list);
 }
 
-multi_union_pw_aff::multi_union_pw_aff(isl::checked::space space, isl::checked::union_pw_aff_list list)
+boolean pw_aff::isa_aff() const
 {
-  auto res = isl_multi_union_pw_aff_from_union_pw_aff_list(space.release(), list.release());
-  ptr = res;
+  auto res = isl_pw_aff_isa_aff(get());
+  return manage(res);
 }
 
-multi_union_pw_aff::multi_union_pw_aff(isl::checked::ctx ctx, const std::string &str)
+boolean pw_aff::isa_multi_aff() const
 {
-  auto res = isl_multi_union_pw_aff_read_from_str(ctx.release(), str.c_str());
-  ptr = res;
+  return isl::checked::pw_multi_aff(*this).isa_multi_aff();
 }
 
-multi_union_pw_aff &multi_union_pw_aff::operator=(multi_union_pw_aff obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+boolean pw_aff::isa_pw_multi_aff() const
+{
+  return isl::checked::union_pw_aff(*this).isa_pw_multi_aff();
 }
 
-multi_union_pw_aff::~multi_union_pw_aff() {
-  if (ptr)
-    isl_multi_union_pw_aff_free(ptr);
+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_give isl_multi_union_pw_aff *multi_union_pw_aff::copy() const & {
-  return isl_multi_union_pw_aff_copy(ptr);
+isl::checked::pw_aff_list pw_aff::list() const
+{
+  return isl::checked::multi_pw_aff(*this).list();
 }
 
-__isl_keep isl_multi_union_pw_aff *multi_union_pw_aff::get() const {
-  return ptr;
+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_give isl_multi_union_pw_aff *multi_union_pw_aff::release() {
-  isl_multi_union_pw_aff *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+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);
 }
 
-bool multi_union_pw_aff::is_null() const {
-  return ptr == nullptr;
+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::ctx multi_union_pw_aff::ctx() const {
-  return isl::checked::ctx(isl_multi_union_pw_aff_get_ctx(ptr));
+isl::checked::pw_aff pw_aff::max(const isl::checked::aff &pwaff2) const
+{
+  return this->max(isl::checked::pw_aff(pwaff2));
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::add(isl::checked::multi_union_pw_aff multi2) const
+isl::checked::multi_val pw_aff::max_multi_val() const
 {
-  auto res = isl_multi_union_pw_aff_add(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).max_multi_val();
 }
 
-isl::checked::union_set multi_union_pw_aff::bind(isl::checked::multi_id tuple) const
+isl::checked::multi_pw_aff pw_aff::min(const isl::checked::multi_pw_aff &multi2) const
 {
-  auto res = isl_multi_union_pw_aff_bind(copy(), tuple.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).min(multi2);
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::coalesce() const
+isl::checked::pw_aff pw_aff::min(isl::checked::pw_aff pwaff2) const
 {
-  auto res = isl_multi_union_pw_aff_coalesce(copy());
+  auto res = isl_pw_aff_min(copy(), pwaff2.release());
   return manage(res);
 }
 
-isl::checked::union_set multi_union_pw_aff::domain() const
+isl::checked::pw_aff pw_aff::min(const isl::checked::aff &pwaff2) const
 {
-  auto res = isl_multi_union_pw_aff_domain(copy());
-  return manage(res);
+  return this->min(isl::checked::pw_aff(pwaff2));
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::flat_range_product(isl::checked::multi_union_pw_aff multi2) const
+isl::checked::multi_val pw_aff::min_multi_val() const
 {
-  auto res = isl_multi_union_pw_aff_flat_range_product(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).min_multi_val();
 }
 
-isl::checked::union_pw_aff multi_union_pw_aff::at(int pos) const
+isl::checked::pw_aff pw_aff::mod(isl::checked::val mod) const
 {
-  auto res = isl_multi_union_pw_aff_get_at(get(), pos);
+  auto res = isl_pw_aff_mod_val(copy(), mod.release());
   return manage(res);
 }
 
-isl::checked::union_pw_aff multi_union_pw_aff::get_at(int pos) const
+isl::checked::pw_aff pw_aff::mod(long mod) const
 {
-  return at(pos);
+  return this->mod(isl::checked::val(ctx(), mod));
 }
 
-isl::checked::union_pw_aff_list multi_union_pw_aff::list() const
+isl::checked::pw_aff pw_aff::mul(isl::checked::pw_aff pwaff2) const
 {
-  auto res = isl_multi_union_pw_aff_get_list(get());
+  auto res = isl_pw_aff_mul(copy(), pwaff2.release());
   return manage(res);
 }
 
-isl::checked::union_pw_aff_list multi_union_pw_aff::get_list() const
+class size pw_aff::n_piece() const
 {
-  return list();
+  return isl::checked::pw_multi_aff(*this).n_piece();
 }
 
-isl::checked::space multi_union_pw_aff::space() const
+isl::checked::set pw_aff::ne_set(isl::checked::pw_aff pwaff2) const
 {
-  auto res = isl_multi_union_pw_aff_get_space(get());
+  auto res = isl_pw_aff_ne_set(copy(), pwaff2.release());
   return manage(res);
 }
 
-isl::checked::space multi_union_pw_aff::get_space() const
+isl::checked::pw_aff pw_aff::neg() const
 {
-  return space();
+  auto res = isl_pw_aff_neg(copy());
+  return manage(res);
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::gist(isl::checked::union_set context) const
+isl::checked::pw_aff pw_aff::param_on_domain(isl::checked::set domain, isl::checked::id id)
 {
-  auto res = isl_multi_union_pw_aff_gist(copy(), context.release());
+  auto res = isl_pw_aff_param_on_domain_id(domain.release(), id.release());
   return manage(res);
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::intersect_domain(isl::checked::union_set uset) const
+boolean pw_aff::plain_is_empty() const
 {
-  auto res = isl_multi_union_pw_aff_intersect_domain(copy(), uset.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).plain_is_empty();
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::intersect_params(isl::checked::set params) const
+boolean pw_aff::plain_is_equal(const isl::checked::multi_pw_aff &multi2) const
 {
-  auto res = isl_multi_union_pw_aff_intersect_params(copy(), params.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).plain_is_equal(multi2);
 }
 
-boolean multi_union_pw_aff::involves_nan() const
+boolean pw_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  auto res = isl_multi_union_pw_aff_involves_nan(get());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).plain_is_equal(multi2);
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::neg() const
+isl::checked::pw_multi_aff pw_aff::preimage_domain_wrapped_domain(const isl::checked::pw_multi_aff &pma2) const
 {
-  auto res = isl_multi_union_pw_aff_neg(copy());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).preimage_domain_wrapped_domain(pma2);
 }
 
-boolean multi_union_pw_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const
+isl::checked::union_pw_multi_aff pw_aff::preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_multi_union_pw_aff_plain_is_equal(get(), multi2.get());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).preimage_domain_wrapped_domain(upma2);
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::pullback(isl::checked::union_pw_multi_aff upma) const
+isl::checked::multi_pw_aff pw_aff::product(const isl::checked::multi_pw_aff &multi2) const
 {
-  auto res = isl_multi_union_pw_aff_pullback_union_pw_multi_aff(copy(), upma.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).product(multi2);
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::range_product(isl::checked::multi_union_pw_aff multi2) const
+isl::checked::pw_multi_aff pw_aff::product(const isl::checked::pw_multi_aff &pma2) const
 {
-  auto res = isl_multi_union_pw_aff_range_product(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).product(pma2);
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::scale(isl::checked::multi_val mv) const
+isl::checked::pw_aff pw_aff::pullback(isl::checked::multi_aff ma) const
 {
-  auto res = isl_multi_union_pw_aff_scale_multi_val(copy(), mv.release());
+  auto res = isl_pw_aff_pullback_multi_aff(copy(), ma.release());
   return manage(res);
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::scale(isl::checked::val v) const
+isl::checked::pw_aff pw_aff::pullback(isl::checked::multi_pw_aff mpa) const
 {
-  auto res = isl_multi_union_pw_aff_scale_val(copy(), v.release());
+  auto res = isl_pw_aff_pullback_multi_pw_aff(copy(), mpa.release());
   return manage(res);
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::scale(long v) const
+isl::checked::pw_aff pw_aff::pullback(isl::checked::pw_multi_aff pma) const
 {
-  return this->scale(isl::checked::val(ctx(), v));
+  auto res = isl_pw_aff_pullback_pw_multi_aff(copy(), pma.release());
+  return manage(res);
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::scale_down(isl::checked::multi_val mv) const
+isl::checked::union_pw_aff pw_aff::pullback(const isl::checked::union_pw_multi_aff &upma) const
 {
-  auto res = isl_multi_union_pw_aff_scale_down_multi_val(copy(), mv.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).pullback(upma);
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::scale_down(isl::checked::val v) const
+isl::checked::pw_multi_aff_list pw_aff::pw_multi_aff_list() const
 {
-  auto res = isl_multi_union_pw_aff_scale_down_val(copy(), v.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).pw_multi_aff_list();
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::scale_down(long v) const
+isl::checked::pw_multi_aff pw_aff::range_factor_domain() const
 {
-  return this->scale_down(isl::checked::val(ctx(), v));
+  return isl::checked::pw_multi_aff(*this).range_factor_domain();
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::set_at(int pos, isl::checked::union_pw_aff el) const
+isl::checked::pw_multi_aff pw_aff::range_factor_range() const
 {
-  auto res = isl_multi_union_pw_aff_set_at(copy(), pos, el.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).range_factor_range();
 }
 
-class size multi_union_pw_aff::size() const
+isl::checked::multi_pw_aff pw_aff::range_product(const isl::checked::multi_pw_aff &multi2) const
 {
-  auto res = isl_multi_union_pw_aff_size(get());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).range_product(multi2);
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::sub(isl::checked::multi_union_pw_aff multi2) const
+isl::checked::multi_union_pw_aff pw_aff::range_product(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  auto res = isl_multi_union_pw_aff_sub(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).range_product(multi2);
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::union_add(isl::checked::multi_union_pw_aff mupa2) const
+isl::checked::pw_multi_aff pw_aff::range_product(const isl::checked::pw_multi_aff &pma2) const
 {
-  auto res = isl_multi_union_pw_aff_union_add(copy(), mupa2.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).range_product(pma2);
 }
 
-isl::checked::multi_union_pw_aff multi_union_pw_aff::zero(isl::checked::space space)
+isl::checked::union_pw_multi_aff pw_aff::range_product(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_multi_union_pw_aff_zero(space.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).range_product(upma2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const multi_union_pw_aff &obj)
+isl::checked::id pw_aff::range_tuple_id() const
 {
-  char *str = isl_multi_union_pw_aff_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return isl::checked::pw_multi_aff(*this).range_tuple_id();
 }
 
-// implementations for isl::multi_val
-multi_val manage(__isl_take isl_multi_val *ptr) {
-  return multi_val(ptr);
-}
-multi_val manage_copy(__isl_keep isl_multi_val *ptr) {
-  ptr = isl_multi_val_copy(ptr);
-  return multi_val(ptr);
+isl::checked::multi_pw_aff pw_aff::reset_range_tuple_id() const
+{
+  return isl::checked::multi_pw_aff(*this).reset_range_tuple_id();
 }
 
-multi_val::multi_val()
-    : ptr(nullptr) {}
-
-multi_val::multi_val(const multi_val &obj)
-    : ptr(nullptr)
+isl::checked::multi_pw_aff pw_aff::scale(const isl::checked::multi_val &mv) const
 {
-  ptr = obj.copy();
+  return isl::checked::multi_pw_aff(*this).scale(mv);
 }
 
-multi_val::multi_val(__isl_take isl_multi_val *ptr)
-    : ptr(ptr) {}
-
-multi_val::multi_val(isl::checked::space space, isl::checked::val_list list)
+isl::checked::pw_aff pw_aff::scale(isl::checked::val v) const
 {
-  auto res = isl_multi_val_from_val_list(space.release(), list.release());
-  ptr = res;
+  auto res = isl_pw_aff_scale_val(copy(), v.release());
+  return manage(res);
 }
 
-multi_val::multi_val(isl::checked::ctx ctx, const std::string &str)
+isl::checked::pw_aff pw_aff::scale(long v) const
 {
-  auto res = isl_multi_val_read_from_str(ctx.release(), str.c_str());
-  ptr = res;
+  return this->scale(isl::checked::val(ctx(), v));
 }
 
-multi_val &multi_val::operator=(multi_val obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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);
 }
 
-multi_val::~multi_val() {
-  if (ptr)
-    isl_multi_val_free(ptr);
+isl::checked::pw_aff pw_aff::scale_down(isl::checked::val f) const
+{
+  auto res = isl_pw_aff_scale_down_val(copy(), f.release());
+  return manage(res);
 }
 
-__isl_give isl_multi_val *multi_val::copy() const & {
-  return isl_multi_val_copy(ptr);
+isl::checked::pw_aff pw_aff::scale_down(long f) const
+{
+  return this->scale_down(isl::checked::val(ctx(), f));
 }
 
-__isl_keep isl_multi_val *multi_val::get() const {
-  return ptr;
+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_give isl_multi_val *multi_val::release() {
-  isl_multi_val *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+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);
 }
 
-bool multi_val::is_null() const {
-  return ptr == nullptr;
+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::ctx multi_val::ctx() const {
-  return isl::checked::ctx(isl_multi_val_get_ctx(ptr));
+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));
 }
 
-isl::checked::multi_val multi_val::add(isl::checked::multi_val multi2) const
+class size pw_aff::size() const
 {
-  auto res = isl_multi_val_add(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::multi_pw_aff(*this).size();
 }
 
-isl::checked::multi_val multi_val::add(isl::checked::val v) const
+isl::checked::space pw_aff::space() const
 {
-  auto res = isl_multi_val_add_val(copy(), v.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).space();
 }
 
-isl::checked::multi_val multi_val::add(long v) const
+isl::checked::multi_pw_aff pw_aff::sub(const isl::checked::multi_pw_aff &multi2) const
 {
-  return this->add(isl::checked::val(ctx(), v));
+  return isl::checked::pw_multi_aff(*this).sub(multi2);
 }
 
-isl::checked::multi_val multi_val::flat_range_product(isl::checked::multi_val multi2) const
+isl::checked::multi_union_pw_aff pw_aff::sub(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  auto res = isl_multi_val_flat_range_product(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).sub(multi2);
 }
 
-isl::checked::val multi_val::at(int pos) const
+isl::checked::pw_aff pw_aff::sub(isl::checked::pw_aff pwaff2) const
 {
-  auto res = isl_multi_val_get_at(get(), pos);
+  auto res = isl_pw_aff_sub(copy(), pwaff2.release());
   return manage(res);
 }
 
-isl::checked::val multi_val::get_at(int pos) const
+isl::checked::pw_multi_aff pw_aff::sub(const isl::checked::pw_multi_aff &pma2) const
 {
-  return at(pos);
+  return isl::checked::pw_multi_aff(*this).sub(pma2);
 }
 
-isl::checked::val_list multi_val::list() const
+isl::checked::union_pw_aff pw_aff::sub(const isl::checked::union_pw_aff &upa2) const
 {
-  auto res = isl_multi_val_get_list(get());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).sub(upa2);
 }
 
-isl::checked::val_list multi_val::get_list() const
+isl::checked::union_pw_multi_aff pw_aff::sub(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  return list();
+  return isl::checked::union_pw_aff(*this).sub(upma2);
 }
 
-isl::checked::space multi_val::space() const
+isl::checked::pw_aff pw_aff::sub(const isl::checked::aff &pwaff2) const
 {
-  auto res = isl_multi_val_get_space(get());
-  return manage(res);
+  return this->sub(isl::checked::pw_aff(pwaff2));
 }
 
-isl::checked::space multi_val::get_space() const
+isl::checked::pw_aff pw_aff::subtract_domain(isl::checked::set set) const
 {
-  return space();
+  auto res = isl_pw_aff_subtract_domain(copy(), set.release());
+  return manage(res);
 }
 
-boolean multi_val::involves_nan() const
+isl::checked::union_pw_aff pw_aff::subtract_domain(const isl::checked::space &space) const
 {
-  auto res = isl_multi_val_involves_nan(get());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).subtract_domain(space);
 }
 
-isl::checked::multi_val multi_val::max(isl::checked::multi_val multi2) const
+isl::checked::union_pw_aff pw_aff::subtract_domain(const isl::checked::union_set &uset) const
 {
-  auto res = isl_multi_val_max(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).subtract_domain(uset);
 }
 
-isl::checked::multi_val multi_val::min(isl::checked::multi_val multi2) const
+isl::checked::pw_aff pw_aff::subtract_domain(const isl::checked::basic_set &set) const
 {
-  auto res = isl_multi_val_min(copy(), multi2.release());
-  return manage(res);
+  return this->subtract_domain(isl::checked::set(set));
 }
 
-isl::checked::multi_val multi_val::neg() const
+isl::checked::pw_aff pw_aff::subtract_domain(const isl::checked::point &set) const
 {
-  auto res = isl_multi_val_neg(copy());
-  return manage(res);
+  return this->subtract_domain(isl::checked::set(set));
 }
 
-boolean multi_val::plain_is_equal(const isl::checked::multi_val &multi2) const
+isl::checked::pw_aff pw_aff::tdiv_q(isl::checked::pw_aff pa2) const
 {
-  auto res = isl_multi_val_plain_is_equal(get(), multi2.get());
+  auto res = isl_pw_aff_tdiv_q(copy(), pa2.release());
   return manage(res);
 }
 
-isl::checked::multi_val multi_val::product(isl::checked::multi_val multi2) const
+isl::checked::pw_aff pw_aff::tdiv_r(isl::checked::pw_aff pa2) const
 {
-  auto res = isl_multi_val_product(copy(), multi2.release());
+  auto res = isl_pw_aff_tdiv_r(copy(), pa2.release());
   return manage(res);
 }
 
-isl::checked::multi_val multi_val::range_product(isl::checked::multi_val multi2) const
+isl::checked::pw_aff_list pw_aff::to_list() const
 {
-  auto res = isl_multi_val_range_product(copy(), multi2.release());
+  auto res = isl_pw_aff_to_list(copy());
   return manage(res);
 }
 
-isl::checked::multi_val multi_val::scale(isl::checked::multi_val mv) const
+isl::checked::multi_pw_aff pw_aff::to_multi_pw_aff() const
 {
-  auto res = isl_multi_val_scale_multi_val(copy(), mv.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).to_multi_pw_aff();
 }
 
-isl::checked::multi_val multi_val::scale(isl::checked::val v) const
+isl::checked::union_pw_aff pw_aff::to_union_pw_aff() const
 {
-  auto res = isl_multi_val_scale_val(copy(), v.release());
+  auto res = isl_pw_aff_to_union_pw_aff(copy());
   return manage(res);
 }
 
-isl::checked::multi_val multi_val::scale(long v) const
+isl::checked::union_pw_multi_aff pw_aff::to_union_pw_multi_aff() const
 {
-  return this->scale(isl::checked::val(ctx(), v));
+  return isl::checked::pw_multi_aff(*this).to_union_pw_multi_aff();
 }
 
-isl::checked::multi_val multi_val::scale_down(isl::checked::multi_val mv) const
+isl::checked::multi_pw_aff pw_aff::unbind_params_insert_domain(const isl::checked::multi_id &domain) const
 {
-  auto res = isl_multi_val_scale_down_multi_val(copy(), mv.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).unbind_params_insert_domain(domain);
 }
 
-isl::checked::multi_val multi_val::scale_down(isl::checked::val v) const
+isl::checked::multi_pw_aff pw_aff::union_add(const isl::checked::multi_pw_aff &mpa2) const
 {
-  auto res = isl_multi_val_scale_down_val(copy(), v.release());
-  return manage(res);
+  return isl::checked::pw_multi_aff(*this).union_add(mpa2);
 }
 
-isl::checked::multi_val multi_val::scale_down(long v) const
+isl::checked::multi_union_pw_aff pw_aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const
 {
-  return this->scale_down(isl::checked::val(ctx(), v));
+  return isl::checked::union_pw_aff(*this).union_add(mupa2);
 }
 
-isl::checked::multi_val multi_val::set_at(int pos, isl::checked::val el) const
+isl::checked::pw_aff pw_aff::union_add(isl::checked::pw_aff pwaff2) const
 {
-  auto res = isl_multi_val_set_at(copy(), pos, el.release());
+  auto res = isl_pw_aff_union_add(copy(), pwaff2.release());
   return manage(res);
 }
 
-isl::checked::multi_val multi_val::set_at(int pos, long el) const
+isl::checked::pw_multi_aff pw_aff::union_add(const isl::checked::pw_multi_aff &pma2) const
 {
-  return this->set_at(pos, isl::checked::val(ctx(), el));
+  return isl::checked::pw_multi_aff(*this).union_add(pma2);
 }
 
-class size multi_val::size() const
+isl::checked::union_pw_aff pw_aff::union_add(const isl::checked::union_pw_aff &upa2) const
 {
-  auto res = isl_multi_val_size(get());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).union_add(upa2);
 }
 
-isl::checked::multi_val multi_val::sub(isl::checked::multi_val multi2) const
+isl::checked::union_pw_multi_aff pw_aff::union_add(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_multi_val_sub(copy(), multi2.release());
-  return manage(res);
+  return isl::checked::union_pw_aff(*this).union_add(upma2);
 }
 
-isl::checked::multi_val multi_val::zero(isl::checked::space space)
+isl::checked::pw_aff pw_aff::union_add(const isl::checked::aff &pwaff2) const
 {
-  auto res = isl_multi_val_zero(space.release());
-  return manage(res);
+  return this->union_add(isl::checked::pw_aff(pwaff2));
 }
 
-inline std::ostream &operator<<(std::ostream &os, const multi_val &obj)
+inline std::ostream &operator<<(std::ostream &os, const pw_aff &obj)
 {
-  char *str = isl_multi_val_to_str(obj.get());
+  char *str = isl_pw_aff_to_str(obj.get());
   if (!str) {
     os.setstate(std::ios_base::badbit);
     return os;
@@ -8043,73 +13387,141 @@ inline std::ostream &operator<<(std::ostream &os, const multi_val &obj)
   return os;
 }
 
-// implementations for isl::point
-point manage(__isl_take isl_point *ptr) {
-  return point(ptr);
+// implementations for isl::pw_aff_list
+pw_aff_list manage(__isl_take isl_pw_aff_list *ptr) {
+  return pw_aff_list(ptr);
 }
-point manage_copy(__isl_keep isl_point *ptr) {
-  ptr = isl_point_copy(ptr);
-  return point(ptr);
+pw_aff_list manage_copy(__isl_keep isl_pw_aff_list *ptr) {
+  ptr = isl_pw_aff_list_copy(ptr);
+  return pw_aff_list(ptr);
 }
 
-point::point()
+pw_aff_list::pw_aff_list()
     : ptr(nullptr) {}
 
-point::point(const point &obj)
+pw_aff_list::pw_aff_list(const pw_aff_list &obj)
     : ptr(nullptr)
 {
   ptr = obj.copy();
 }
 
-point::point(__isl_take isl_point *ptr)
+pw_aff_list::pw_aff_list(__isl_take isl_pw_aff_list *ptr)
     : ptr(ptr) {}
 
-point &point::operator=(point obj) {
+pw_aff_list::pw_aff_list(isl::checked::ctx ctx, int n)
+{
+  auto res = isl_pw_aff_list_alloc(ctx.release(), n);
+  ptr = res;
+}
+
+pw_aff_list::pw_aff_list(isl::checked::pw_aff el)
+{
+  auto res = isl_pw_aff_list_from_pw_aff(el.release());
+  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;
 }
 
-point::~point() {
+pw_aff_list::~pw_aff_list() {
   if (ptr)
-    isl_point_free(ptr);
+    isl_pw_aff_list_free(ptr);
 }
 
-__isl_give isl_point *point::copy() const & {
-  return isl_point_copy(ptr);
+__isl_give isl_pw_aff_list *pw_aff_list::copy() const & {
+  return isl_pw_aff_list_copy(ptr);
 }
 
-__isl_keep isl_point *point::get() const {
+__isl_keep isl_pw_aff_list *pw_aff_list::get() const {
   return ptr;
 }
 
-__isl_give isl_point *point::release() {
-  isl_point *tmp = ptr;
+__isl_give isl_pw_aff_list *pw_aff_list::release() {
+  isl_pw_aff_list *tmp = ptr;
   ptr = nullptr;
   return tmp;
 }
 
-bool point::is_null() const {
-  return ptr == nullptr;
+bool pw_aff_list::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::checked::ctx pw_aff_list::ctx() const {
+  return isl::checked::ctx(isl_pw_aff_list_get_ctx(ptr));
+}
+
+isl::checked::pw_aff_list pw_aff_list::add(isl::checked::pw_aff el) const
+{
+  auto res = isl_pw_aff_list_add(copy(), el.release());
+  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());
+  return manage(res);
+}
+
+isl::checked::pw_aff_list pw_aff_list::concat(isl::checked::pw_aff_list list2) const
+{
+  auto res = isl_pw_aff_list_concat(copy(), list2.release());
+  return manage(res);
+}
+
+isl::checked::pw_aff_list pw_aff_list::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl_pw_aff_list_drop(copy(), first, n);
+  return manage(res);
 }
 
-isl::checked::ctx point::ctx() const {
-  return isl::checked::ctx(isl_point_get_ctx(ptr));
+stat pw_aff_list::foreach(const std::function<stat(isl::checked::pw_aff)> &fn) const
+{
+  struct fn_data {
+    std::function<stat(isl::checked::pw_aff)> func;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_pw_aff *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_pw_aff_list_foreach(get(), fn_lambda, &fn_data);
+  return manage(res);
 }
 
-isl::checked::multi_val point::multi_val() const
+isl::checked::pw_aff_list pw_aff_list::insert(unsigned int pos, isl::checked::pw_aff el) const
 {
-  auto res = isl_point_get_multi_val(get());
+  auto res = isl_pw_aff_list_insert(copy(), pos, el.release());
   return manage(res);
 }
 
-isl::checked::multi_val point::get_multi_val() const
+class size pw_aff_list::size() const
 {
-  return multi_val();
+  auto res = isl_pw_aff_list_size(get());
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const point &obj)
+inline std::ostream &operator<<(std::ostream &os, const pw_aff_list &obj)
 {
-  char *str = isl_point_to_str(obj.get());
+  char *str = isl_pw_aff_list_to_str(obj.get());
   if (!str) {
     os.setstate(std::ios_base::badbit);
     return os;
@@ -8119,793 +13531,753 @@ inline std::ostream &operator<<(std::ostream &os, const point &obj)
   return os;
 }
 
-// implementations for isl::pw_aff
-pw_aff manage(__isl_take isl_pw_aff *ptr) {
-  return pw_aff(ptr);
+// implementations for isl::pw_multi_aff
+pw_multi_aff manage(__isl_take isl_pw_multi_aff *ptr) {
+  return pw_multi_aff(ptr);
 }
-pw_aff manage_copy(__isl_keep isl_pw_aff *ptr) {
-  ptr = isl_pw_aff_copy(ptr);
-  return pw_aff(ptr);
+pw_multi_aff manage_copy(__isl_keep isl_pw_multi_aff *ptr) {
+  ptr = isl_pw_multi_aff_copy(ptr);
+  return pw_multi_aff(ptr);
 }
 
-pw_aff::pw_aff()
+pw_multi_aff::pw_multi_aff()
     : ptr(nullptr) {}
 
-pw_aff::pw_aff(const pw_aff &obj)
+pw_multi_aff::pw_multi_aff(const pw_multi_aff &obj)
     : ptr(nullptr)
 {
   ptr = obj.copy();
 }
 
-pw_aff::pw_aff(__isl_take isl_pw_aff *ptr)
+pw_multi_aff::pw_multi_aff(__isl_take isl_pw_multi_aff *ptr)
     : ptr(ptr) {}
 
-pw_aff::pw_aff(isl::checked::aff aff)
+pw_multi_aff::pw_multi_aff(isl::checked::multi_aff ma)
 {
-  auto res = isl_pw_aff_from_aff(aff.release());
+  auto res = isl_pw_multi_aff_from_multi_aff(ma.release());
   ptr = res;
 }
 
-pw_aff::pw_aff(isl::checked::ctx ctx, const std::string &str)
+pw_multi_aff::pw_multi_aff(isl::checked::pw_aff pa)
 {
-  auto res = isl_pw_aff_read_from_str(ctx.release(), str.c_str());
+  auto res = isl_pw_multi_aff_from_pw_aff(pa.release());
   ptr = res;
 }
 
-pw_aff &pw_aff::operator=(pw_aff obj) {
+pw_multi_aff::pw_multi_aff(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_pw_multi_aff_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
+pw_multi_aff &pw_multi_aff::operator=(pw_multi_aff obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-pw_aff::~pw_aff() {
+pw_multi_aff::~pw_multi_aff() {
   if (ptr)
-    isl_pw_aff_free(ptr);
+    isl_pw_multi_aff_free(ptr);
 }
 
-__isl_give isl_pw_aff *pw_aff::copy() const & {
-  return isl_pw_aff_copy(ptr);
+__isl_give isl_pw_multi_aff *pw_multi_aff::copy() const & {
+  return isl_pw_multi_aff_copy(ptr);
 }
 
-__isl_keep isl_pw_aff *pw_aff::get() const {
+__isl_keep isl_pw_multi_aff *pw_multi_aff::get() const {
   return ptr;
 }
 
-__isl_give isl_pw_aff *pw_aff::release() {
-  isl_pw_aff *tmp = ptr;
+__isl_give isl_pw_multi_aff *pw_multi_aff::release() {
+  isl_pw_multi_aff *tmp = ptr;
   ptr = nullptr;
   return tmp;
 }
 
-bool pw_aff::is_null() const {
+bool pw_multi_aff::is_null() const {
   return ptr == nullptr;
 }
 
-isl::checked::ctx pw_aff::ctx() const {
-  return isl::checked::ctx(isl_pw_aff_get_ctx(ptr));
-}
-
-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_aff pw_aff::add_constant(isl::checked::val v) const
-{
-  auto res = isl_pw_aff_add_constant_val(copy(), v.release());
-  return manage(res);
+isl::checked::ctx pw_multi_aff::ctx() const {
+  return isl::checked::ctx(isl_pw_multi_aff_get_ctx(ptr));
 }
 
-isl::checked::pw_aff pw_aff::add_constant(long v) const
+isl::checked::multi_pw_aff pw_multi_aff::add(const isl::checked::multi_pw_aff &multi2) const
 {
-  return this->add_constant(isl::checked::val(ctx(), v));
+  return isl::checked::multi_pw_aff(*this).add(multi2);
 }
 
-isl::checked::aff pw_aff::as_aff() const
+isl::checked::multi_union_pw_aff pw_multi_aff::add(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  auto res = isl_pw_aff_as_aff(copy());
-  return manage(res);
+  return isl::checked::multi_pw_aff(*this).add(multi2);
 }
 
-isl::checked::set pw_aff::bind(isl::checked::id id) const
+isl::checked::pw_multi_aff pw_multi_aff::add(isl::checked::pw_multi_aff pma2) const
 {
-  auto res = isl_pw_aff_bind_id(copy(), id.release());
+  auto res = isl_pw_multi_aff_add(copy(), pma2.release());
   return manage(res);
 }
 
-isl::checked::set pw_aff::bind(const std::string &id) const
+isl::checked::union_pw_multi_aff pw_multi_aff::add(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  return this->bind(isl::checked::id(ctx(), id));
+  return isl::checked::union_pw_multi_aff(*this).add(upma2);
 }
 
-isl::checked::pw_aff pw_aff::bind_domain(isl::checked::multi_id tuple) const
+isl::checked::pw_multi_aff pw_multi_aff::add(const isl::checked::multi_aff &pma2) const
 {
-  auto res = isl_pw_aff_bind_domain(copy(), tuple.release());
-  return manage(res);
+  return this->add(isl::checked::pw_multi_aff(pma2));
 }
 
-isl::checked::pw_aff pw_aff::bind_domain_wrapped_domain(isl::checked::multi_id tuple) const
+isl::checked::pw_multi_aff pw_multi_aff::add(const isl::checked::pw_aff &pma2) const
 {
-  auto res = isl_pw_aff_bind_domain_wrapped_domain(copy(), tuple.release());
-  return manage(res);
+  return this->add(isl::checked::pw_multi_aff(pma2));
 }
 
-isl::checked::pw_aff pw_aff::ceil() const
+isl::checked::pw_multi_aff pw_multi_aff::add_constant(isl::checked::multi_val mv) const
 {
-  auto res = isl_pw_aff_ceil(copy());
+  auto res = isl_pw_multi_aff_add_constant_multi_val(copy(), mv.release());
   return manage(res);
 }
 
-isl::checked::pw_aff pw_aff::coalesce() const
+isl::checked::pw_multi_aff pw_multi_aff::add_constant(isl::checked::val v) const
 {
-  auto res = isl_pw_aff_coalesce(copy());
+  auto res = isl_pw_multi_aff_add_constant_val(copy(), v.release());
   return manage(res);
 }
 
-isl::checked::pw_aff pw_aff::cond(isl::checked::pw_aff pwaff_true, isl::checked::pw_aff pwaff_false) const
+isl::checked::pw_multi_aff pw_multi_aff::add_constant(long v) const
 {
-  auto res = isl_pw_aff_cond(copy(), pwaff_true.release(), pwaff_false.release());
-  return manage(res);
+  return this->add_constant(isl::checked::val(ctx(), v));
 }
 
-isl::checked::pw_aff pw_aff::div(isl::checked::pw_aff pa2) const
+isl::checked::union_pw_multi_aff pw_multi_aff::apply(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_pw_aff_div(copy(), pa2.release());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).apply(upma2);
 }
 
-isl::checked::set pw_aff::domain() const
+isl::checked::map pw_multi_aff::as_map() const
 {
-  auto res = isl_pw_aff_domain(copy());
+  auto res = isl_pw_multi_aff_as_map(copy());
   return manage(res);
 }
 
-isl::checked::set pw_aff::eq_set(isl::checked::pw_aff pwaff2) const
+isl::checked::multi_aff pw_multi_aff::as_multi_aff() const
 {
-  auto res = isl_pw_aff_eq_set(copy(), pwaff2.release());
+  auto res = isl_pw_multi_aff_as_multi_aff(copy());
   return manage(res);
 }
 
-isl::checked::val pw_aff::eval(isl::checked::point pnt) const
+isl::checked::multi_union_pw_aff pw_multi_aff::as_multi_union_pw_aff() const
 {
-  auto res = isl_pw_aff_eval(copy(), pnt.release());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).as_multi_union_pw_aff();
 }
 
-isl::checked::pw_aff pw_aff::floor() const
+isl::checked::pw_multi_aff pw_multi_aff::as_pw_multi_aff() const
 {
-  auto res = isl_pw_aff_floor(copy());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).as_pw_multi_aff();
 }
 
-isl::checked::set pw_aff::ge_set(isl::checked::pw_aff pwaff2) const
+isl::checked::set pw_multi_aff::as_set() const
 {
-  auto res = isl_pw_aff_ge_set(copy(), pwaff2.release());
+  auto res = isl_pw_multi_aff_as_set(copy());
   return manage(res);
 }
 
-isl::checked::pw_aff pw_aff::gist(isl::checked::set context) const
+isl::checked::union_map pw_multi_aff::as_union_map() const
 {
-  auto res = isl_pw_aff_gist(copy(), context.release());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).as_union_map();
 }
 
-isl::checked::set pw_aff::gt_set(isl::checked::pw_aff pwaff2) const
+isl::checked::pw_aff pw_multi_aff::at(int pos) const
 {
-  auto res = isl_pw_aff_gt_set(copy(), pwaff2.release());
+  auto res = isl_pw_multi_aff_get_at(get(), pos);
   return manage(res);
 }
 
-isl::checked::pw_aff pw_aff::insert_domain(isl::checked::space domain) const
+isl::checked::pw_aff pw_multi_aff::get_at(int pos) const
 {
-  auto res = isl_pw_aff_insert_domain(copy(), domain.release());
-  return manage(res);
+  return at(pos);
 }
 
-isl::checked::pw_aff pw_aff::intersect_domain(isl::checked::set set) const
+isl::checked::set pw_multi_aff::bind(const isl::checked::multi_id &tuple) const
 {
-  auto res = isl_pw_aff_intersect_domain(copy(), set.release());
-  return manage(res);
+  return isl::checked::multi_pw_aff(*this).bind(tuple);
 }
 
-isl::checked::pw_aff pw_aff::intersect_params(isl::checked::set set) const
+isl::checked::pw_multi_aff pw_multi_aff::bind_domain(isl::checked::multi_id tuple) const
 {
-  auto res = isl_pw_aff_intersect_params(copy(), set.release());
+  auto res = isl_pw_multi_aff_bind_domain(copy(), tuple.release());
   return manage(res);
 }
 
-boolean pw_aff::isa_aff() const
+isl::checked::pw_multi_aff pw_multi_aff::bind_domain_wrapped_domain(isl::checked::multi_id tuple) const
 {
-  auto res = isl_pw_aff_isa_aff(get());
+  auto res = isl_pw_multi_aff_bind_domain_wrapped_domain(copy(), tuple.release());
   return manage(res);
 }
 
-isl::checked::set pw_aff::le_set(isl::checked::pw_aff pwaff2) const
+isl::checked::pw_multi_aff pw_multi_aff::coalesce() const
 {
-  auto res = isl_pw_aff_le_set(copy(), pwaff2.release());
+  auto res = isl_pw_multi_aff_coalesce(copy());
   return manage(res);
 }
 
-isl::checked::set pw_aff::lt_set(isl::checked::pw_aff pwaff2) const
+isl::checked::set pw_multi_aff::domain() const
 {
-  auto res = isl_pw_aff_lt_set(copy(), pwaff2.release());
+  auto res = isl_pw_multi_aff_domain(copy());
   return manage(res);
 }
 
-isl::checked::pw_aff pw_aff::max(isl::checked::pw_aff pwaff2) const
+isl::checked::pw_multi_aff pw_multi_aff::domain_map(isl::checked::space space)
 {
-  auto res = isl_pw_aff_max(copy(), pwaff2.release());
+  auto res = isl_pw_multi_aff_domain_map(space.release());
   return manage(res);
 }
 
-isl::checked::pw_aff pw_aff::min(isl::checked::pw_aff pwaff2) const
+isl::checked::pw_multi_aff pw_multi_aff::extract_pw_multi_aff(const isl::checked::space &space) const
 {
-  auto res = isl_pw_aff_min(copy(), pwaff2.release());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).extract_pw_multi_aff(space);
 }
 
-isl::checked::pw_aff pw_aff::mod(isl::checked::val mod) const
+isl::checked::multi_pw_aff pw_multi_aff::flat_range_product(const isl::checked::multi_pw_aff &multi2) const
 {
-  auto res = isl_pw_aff_mod_val(copy(), mod.release());
-  return manage(res);
+  return isl::checked::multi_pw_aff(*this).flat_range_product(multi2);
 }
 
-isl::checked::pw_aff pw_aff::mod(long mod) const
+isl::checked::multi_union_pw_aff pw_multi_aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  return this->mod(isl::checked::val(ctx(), mod));
+  return isl::checked::multi_pw_aff(*this).flat_range_product(multi2);
 }
 
-isl::checked::pw_aff pw_aff::mul(isl::checked::pw_aff pwaff2) const
+isl::checked::pw_multi_aff pw_multi_aff::flat_range_product(isl::checked::pw_multi_aff pma2) const
 {
-  auto res = isl_pw_aff_mul(copy(), pwaff2.release());
+  auto res = isl_pw_multi_aff_flat_range_product(copy(), pma2.release());
   return manage(res);
 }
 
-isl::checked::set pw_aff::ne_set(isl::checked::pw_aff pwaff2) const
+isl::checked::union_pw_multi_aff pw_multi_aff::flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_pw_aff_ne_set(copy(), pwaff2.release());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).flat_range_product(upma2);
 }
 
-isl::checked::pw_aff pw_aff::neg() const
+isl::checked::pw_multi_aff pw_multi_aff::flat_range_product(const isl::checked::multi_aff &pma2) const
 {
-  auto res = isl_pw_aff_neg(copy());
-  return manage(res);
+  return this->flat_range_product(isl::checked::pw_multi_aff(pma2));
 }
 
-isl::checked::pw_aff pw_aff::param_on_domain(isl::checked::set domain, isl::checked::id id)
+isl::checked::pw_multi_aff pw_multi_aff::flat_range_product(const isl::checked::pw_aff &pma2) const
 {
-  auto res = isl_pw_aff_param_on_domain_id(domain.release(), id.release());
-  return manage(res);
+  return this->flat_range_product(isl::checked::pw_multi_aff(pma2));
 }
 
-isl::checked::pw_aff pw_aff::pullback(isl::checked::multi_aff ma) const
+stat pw_multi_aff::foreach_piece(const std::function<stat(isl::checked::set, isl::checked::multi_aff)> &fn) const
 {
-  auto res = isl_pw_aff_pullback_multi_aff(copy(), ma.release());
+  struct fn_data {
+    std::function<stat(isl::checked::set, isl::checked::multi_aff)> func;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_set *arg_0, isl_multi_aff *arg_1, void *arg_2) -> isl_stat {
+    auto *data = static_cast<struct fn_data *>(arg_2);
+    auto ret = (data->func)(manage(arg_0), manage(arg_1));
+    return ret.release();
+  };
+  auto res = isl_pw_multi_aff_foreach_piece(get(), fn_lambda, &fn_data);
   return manage(res);
 }
 
-isl::checked::pw_aff pw_aff::pullback(isl::checked::multi_pw_aff mpa) const
+isl::checked::pw_multi_aff pw_multi_aff::gist(isl::checked::set set) const
 {
-  auto res = isl_pw_aff_pullback_multi_pw_aff(copy(), mpa.release());
+  auto res = isl_pw_multi_aff_gist(copy(), set.release());
   return manage(res);
 }
 
-isl::checked::pw_aff pw_aff::pullback(isl::checked::pw_multi_aff pma) const
+isl::checked::union_pw_multi_aff pw_multi_aff::gist(const isl::checked::union_set &context) const
 {
-  auto res = isl_pw_aff_pullback_pw_multi_aff(copy(), pma.release());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).gist(context);
 }
 
-isl::checked::pw_aff pw_aff::scale(isl::checked::val v) const
+isl::checked::pw_multi_aff pw_multi_aff::gist(const isl::checked::basic_set &set) const
 {
-  auto res = isl_pw_aff_scale_val(copy(), v.release());
-  return manage(res);
+  return this->gist(isl::checked::set(set));
 }
 
-isl::checked::pw_aff pw_aff::scale(long v) const
+isl::checked::pw_multi_aff pw_multi_aff::gist(const isl::checked::point &set) const
 {
-  return this->scale(isl::checked::val(ctx(), v));
+  return this->gist(isl::checked::set(set));
 }
 
-isl::checked::pw_aff pw_aff::scale_down(isl::checked::val f) const
+boolean pw_multi_aff::has_range_tuple_id() const
 {
-  auto res = isl_pw_aff_scale_down_val(copy(), f.release());
+  auto res = isl_pw_multi_aff_has_range_tuple_id(get());
   return manage(res);
 }
 
-isl::checked::pw_aff pw_aff::scale_down(long f) const
+isl::checked::multi_pw_aff pw_multi_aff::identity() const
 {
-  return this->scale_down(isl::checked::val(ctx(), f));
+  return isl::checked::multi_pw_aff(*this).identity();
 }
 
-isl::checked::pw_aff pw_aff::sub(isl::checked::pw_aff pwaff2) const
+isl::checked::pw_multi_aff pw_multi_aff::identity_on_domain(isl::checked::space space)
 {
-  auto res = isl_pw_aff_sub(copy(), pwaff2.release());
+  auto res = isl_pw_multi_aff_identity_on_domain_space(space.release());
   return manage(res);
 }
 
-isl::checked::pw_aff pw_aff::subtract_domain(isl::checked::set set) const
+isl::checked::pw_multi_aff pw_multi_aff::insert_domain(isl::checked::space domain) const
 {
-  auto res = isl_pw_aff_subtract_domain(copy(), set.release());
+  auto res = isl_pw_multi_aff_insert_domain(copy(), domain.release());
   return manage(res);
 }
 
-isl::checked::pw_aff pw_aff::tdiv_q(isl::checked::pw_aff pa2) const
+isl::checked::pw_multi_aff pw_multi_aff::intersect_domain(isl::checked::set set) const
 {
-  auto res = isl_pw_aff_tdiv_q(copy(), pa2.release());
+  auto res = isl_pw_multi_aff_intersect_domain(copy(), set.release());
   return manage(res);
 }
 
-isl::checked::pw_aff pw_aff::tdiv_r(isl::checked::pw_aff pa2) const
+isl::checked::union_pw_multi_aff pw_multi_aff::intersect_domain(const isl::checked::space &space) const
 {
-  auto res = isl_pw_aff_tdiv_r(copy(), pa2.release());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).intersect_domain(space);
 }
 
-isl::checked::pw_aff pw_aff::union_add(isl::checked::pw_aff pwaff2) const
+isl::checked::union_pw_multi_aff pw_multi_aff::intersect_domain(const isl::checked::union_set &uset) const
 {
-  auto res = isl_pw_aff_union_add(copy(), pwaff2.release());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).intersect_domain(uset);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const pw_aff &obj)
+isl::checked::pw_multi_aff pw_multi_aff::intersect_domain(const isl::checked::basic_set &set) const
 {
-  char *str = isl_pw_aff_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  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));
 }
 
-// implementations for isl::pw_aff_list
-pw_aff_list manage(__isl_take isl_pw_aff_list *ptr) {
-  return pw_aff_list(ptr);
+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);
 }
-pw_aff_list manage_copy(__isl_keep isl_pw_aff_list *ptr) {
-  ptr = isl_pw_aff_list_copy(ptr);
-  return pw_aff_list(ptr);
+
+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);
 }
 
-pw_aff_list::pw_aff_list()
-    : ptr(nullptr) {}
+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());
+  return manage(res);
+}
 
-pw_aff_list::pw_aff_list(const pw_aff_list &obj)
-    : ptr(nullptr)
+boolean pw_multi_aff::involves_locals() const
 {
-  ptr = obj.copy();
+  auto res = isl_pw_multi_aff_involves_locals(get());
+  return manage(res);
 }
 
-pw_aff_list::pw_aff_list(__isl_take isl_pw_aff_list *ptr)
-    : ptr(ptr) {}
+boolean pw_multi_aff::involves_nan() const
+{
+  return isl::checked::multi_pw_aff(*this).involves_nan();
+}
 
-pw_aff_list::pw_aff_list(isl::checked::ctx ctx, int n)
+boolean pw_multi_aff::involves_param(const isl::checked::id &id) const
 {
-  auto res = isl_pw_aff_list_alloc(ctx.release(), n);
-  ptr = res;
+  return isl::checked::multi_pw_aff(*this).involves_param(id);
 }
 
-pw_aff_list::pw_aff_list(isl::checked::pw_aff el)
+boolean pw_multi_aff::involves_param(const std::string &id) const
 {
-  auto res = isl_pw_aff_list_from_pw_aff(el.release());
-  ptr = res;
+  return this->involves_param(isl::checked::id(ctx(), id));
 }
 
-pw_aff_list &pw_aff_list::operator=(pw_aff_list obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+boolean pw_multi_aff::involves_param(const isl::checked::id_list &list) const
+{
+  return isl::checked::multi_pw_aff(*this).involves_param(list);
 }
 
-pw_aff_list::~pw_aff_list() {
-  if (ptr)
-    isl_pw_aff_list_free(ptr);
+boolean pw_multi_aff::isa_multi_aff() const
+{
+  auto res = isl_pw_multi_aff_isa_multi_aff(get());
+  return manage(res);
 }
 
-__isl_give isl_pw_aff_list *pw_aff_list::copy() const & {
-  return isl_pw_aff_list_copy(ptr);
+boolean pw_multi_aff::isa_pw_multi_aff() const
+{
+  return isl::checked::union_pw_multi_aff(*this).isa_pw_multi_aff();
 }
 
-__isl_keep isl_pw_aff_list *pw_aff_list::get() const {
-  return ptr;
+isl::checked::pw_aff_list pw_multi_aff::list() const
+{
+  return isl::checked::multi_pw_aff(*this).list();
 }
 
-__isl_give isl_pw_aff_list *pw_aff_list::release() {
-  isl_pw_aff_list *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+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);
 }
 
-bool pw_aff_list::is_null() const {
-  return ptr == nullptr;
+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::ctx pw_aff_list::ctx() const {
-  return isl::checked::ctx(isl_pw_aff_list_get_ctx(ptr));
+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::pw_aff_list pw_aff_list::add(isl::checked::pw_aff el) const
+isl::checked::multi_val pw_multi_aff::min_multi_val() const
 {
-  auto res = isl_pw_aff_list_add(copy(), el.release());
+  auto res = isl_pw_multi_aff_min_multi_val(copy());
   return manage(res);
 }
 
-isl::checked::pw_aff_list pw_aff_list::clear() const
+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_aff_list_clear(copy());
+  auto res = isl_pw_multi_aff_multi_val_on_domain(domain.release(), mv.release());
   return manage(res);
 }
 
-isl::checked::pw_aff_list pw_aff_list::concat(isl::checked::pw_aff_list list2) const
+class size pw_multi_aff::n_piece() const
 {
-  auto res = isl_pw_aff_list_concat(copy(), list2.release());
+  auto res = isl_pw_multi_aff_n_piece(get());
   return manage(res);
 }
 
-isl::checked::pw_aff_list pw_aff_list::drop(unsigned int first, unsigned int n) const
+isl::checked::multi_pw_aff pw_multi_aff::neg() const
 {
-  auto res = isl_pw_aff_list_drop(copy(), first, n);
-  return manage(res);
+  return isl::checked::multi_pw_aff(*this).neg();
 }
 
-stat pw_aff_list::foreach(const std::function<stat(isl::checked::pw_aff)> &fn) const
+boolean pw_multi_aff::plain_is_empty() const
 {
-  struct fn_data {
-    std::function<stat(isl::checked::pw_aff)> func;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_pw_aff *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_pw_aff_list_foreach(get(), fn_lambda, &fn_data);
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).plain_is_empty();
 }
 
-isl::checked::pw_aff pw_aff_list::at(int index) const
+boolean pw_multi_aff::plain_is_equal(const isl::checked::multi_pw_aff &multi2) const
 {
-  auto res = isl_pw_aff_list_get_at(get(), index);
-  return manage(res);
+  return isl::checked::multi_pw_aff(*this).plain_is_equal(multi2);
 }
 
-isl::checked::pw_aff pw_aff_list::get_at(int index) const
+boolean pw_multi_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  return at(index);
+  return isl::checked::multi_pw_aff(*this).plain_is_equal(multi2);
 }
 
-isl::checked::pw_aff_list pw_aff_list::insert(unsigned int pos, isl::checked::pw_aff el) const
+isl::checked::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(isl::checked::pw_multi_aff pma2) const
 {
-  auto res = isl_pw_aff_list_insert(copy(), pos, el.release());
+  auto res = isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(copy(), pma2.release());
   return manage(res);
 }
 
-class size pw_aff_list::size() const
+isl::checked::union_pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_pw_aff_list_size(get());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).preimage_domain_wrapped_domain(upma2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const pw_aff_list &obj)
+isl::checked::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::checked::multi_aff &pma2) const
 {
-  char *str = isl_pw_aff_list_to_str(obj.get());
-  if (!str) {
-    os.setstate(std::ios_base::badbit);
-    return os;
-  }
-  os << str;
-  free(str);
-  return os;
+  return this->preimage_domain_wrapped_domain(isl::checked::pw_multi_aff(pma2));
 }
 
-// implementations for isl::pw_multi_aff
-pw_multi_aff manage(__isl_take isl_pw_multi_aff *ptr) {
-  return pw_multi_aff(ptr);
+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));
 }
-pw_multi_aff manage_copy(__isl_keep isl_pw_multi_aff *ptr) {
-  ptr = isl_pw_multi_aff_copy(ptr);
-  return pw_multi_aff(ptr);
+
+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);
 }
 
-pw_multi_aff::pw_multi_aff()
-    : ptr(nullptr) {}
+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);
+}
 
-pw_multi_aff::pw_multi_aff(const pw_multi_aff &obj)
-    : ptr(nullptr)
+isl::checked::pw_multi_aff pw_multi_aff::product(const isl::checked::multi_aff &pma2) const
 {
-  ptr = obj.copy();
+  return this->product(isl::checked::pw_multi_aff(pma2));
 }
 
-pw_multi_aff::pw_multi_aff(__isl_take isl_pw_multi_aff *ptr)
-    : ptr(ptr) {}
+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));
+}
 
-pw_multi_aff::pw_multi_aff(isl::checked::multi_aff ma)
+isl::checked::multi_pw_aff pw_multi_aff::pullback(const isl::checked::multi_pw_aff &mpa2) const
 {
-  auto res = isl_pw_multi_aff_from_multi_aff(ma.release());
-  ptr = res;
+  return isl::checked::multi_pw_aff(*this).pullback(mpa2);
 }
 
-pw_multi_aff::pw_multi_aff(isl::checked::pw_aff pa)
+isl::checked::pw_multi_aff pw_multi_aff::pullback(isl::checked::multi_aff ma) const
 {
-  auto res = isl_pw_multi_aff_from_pw_aff(pa.release());
-  ptr = res;
+  auto res = isl_pw_multi_aff_pullback_multi_aff(copy(), ma.release());
+  return manage(res);
 }
 
-pw_multi_aff::pw_multi_aff(isl::checked::ctx ctx, const std::string &str)
+isl::checked::pw_multi_aff pw_multi_aff::pullback(isl::checked::pw_multi_aff pma2) const
 {
-  auto res = isl_pw_multi_aff_read_from_str(ctx.release(), str.c_str());
-  ptr = res;
+  auto res = isl_pw_multi_aff_pullback_pw_multi_aff(copy(), pma2.release());
+  return manage(res);
 }
 
-pw_multi_aff &pw_multi_aff::operator=(pw_multi_aff obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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);
 }
 
-pw_multi_aff::~pw_multi_aff() {
-  if (ptr)
-    isl_pw_multi_aff_free(ptr);
+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_give isl_pw_multi_aff *pw_multi_aff::copy() const & {
-  return isl_pw_multi_aff_copy(ptr);
+isl::checked::pw_multi_aff pw_multi_aff::range_factor_domain() const
+{
+  auto res = isl_pw_multi_aff_range_factor_domain(copy());
+  return manage(res);
 }
 
-__isl_keep isl_pw_multi_aff *pw_multi_aff::get() const {
-  return ptr;
+isl::checked::pw_multi_aff pw_multi_aff::range_factor_range() const
+{
+  auto res = isl_pw_multi_aff_range_factor_range(copy());
+  return manage(res);
 }
 
-__isl_give isl_pw_multi_aff *pw_multi_aff::release() {
-  isl_pw_multi_aff *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+isl::checked::pw_multi_aff pw_multi_aff::range_map(isl::checked::space space)
+{
+  auto res = isl_pw_multi_aff_range_map(space.release());
+  return manage(res);
 }
 
-bool pw_multi_aff::is_null() const {
-  return ptr == nullptr;
+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::ctx pw_multi_aff::ctx() const {
-  return isl::checked::ctx(isl_pw_multi_aff_get_ctx(ptr));
+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::add(isl::checked::pw_multi_aff pma2) const
+isl::checked::pw_multi_aff pw_multi_aff::range_product(isl::checked::pw_multi_aff pma2) const
 {
-  auto res = isl_pw_multi_aff_add(copy(), pma2.release());
+  auto res = isl_pw_multi_aff_range_product(copy(), pma2.release());
   return manage(res);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::add_constant(isl::checked::multi_val mv) const
+isl::checked::union_pw_multi_aff pw_multi_aff::range_product(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_pw_multi_aff_add_constant_multi_val(copy(), mv.release());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).range_product(upma2);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::add_constant(isl::checked::val v) const
+isl::checked::pw_multi_aff pw_multi_aff::range_product(const isl::checked::multi_aff &pma2) const
 {
-  auto res = isl_pw_multi_aff_add_constant_val(copy(), v.release());
-  return manage(res);
+  return this->range_product(isl::checked::pw_multi_aff(pma2));
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::add_constant(long v) const
+isl::checked::pw_multi_aff pw_multi_aff::range_product(const isl::checked::pw_aff &pma2) const
 {
-  return this->add_constant(isl::checked::val(ctx(), v));
+  return this->range_product(isl::checked::pw_multi_aff(pma2));
 }
 
-isl::checked::multi_aff pw_multi_aff::as_multi_aff() const
+isl::checked::id pw_multi_aff::range_tuple_id() const
 {
-  auto res = isl_pw_multi_aff_as_multi_aff(copy());
+  auto res = isl_pw_multi_aff_get_range_tuple_id(get());
   return manage(res);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::bind_domain(isl::checked::multi_id tuple) const
+isl::checked::id pw_multi_aff::get_range_tuple_id() const
 {
-  auto res = isl_pw_multi_aff_bind_domain(copy(), tuple.release());
-  return manage(res);
+  return range_tuple_id();
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::bind_domain_wrapped_domain(isl::checked::multi_id tuple) const
+isl::checked::multi_pw_aff pw_multi_aff::reset_range_tuple_id() const
 {
-  auto res = isl_pw_multi_aff_bind_domain_wrapped_domain(copy(), tuple.release());
-  return manage(res);
+  return isl::checked::multi_pw_aff(*this).reset_range_tuple_id();
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::coalesce() const
+isl::checked::multi_pw_aff pw_multi_aff::scale(const isl::checked::multi_val &mv) const
 {
-  auto res = isl_pw_multi_aff_coalesce(copy());
-  return manage(res);
+  return isl::checked::multi_pw_aff(*this).scale(mv);
 }
 
-isl::checked::set pw_multi_aff::domain() const
+isl::checked::pw_multi_aff pw_multi_aff::scale(isl::checked::val v) const
 {
-  auto res = isl_pw_multi_aff_domain(copy());
+  auto res = isl_pw_multi_aff_scale_val(copy(), v.release());
   return manage(res);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::domain_map(isl::checked::space space)
+isl::checked::pw_multi_aff pw_multi_aff::scale(long v) const
 {
-  auto res = isl_pw_multi_aff_domain_map(space.release());
-  return manage(res);
+  return this->scale(isl::checked::val(ctx(), v));
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::flat_range_product(isl::checked::pw_multi_aff pma2) const
+isl::checked::multi_pw_aff pw_multi_aff::scale_down(const isl::checked::multi_val &mv) const
 {
-  auto res = isl_pw_multi_aff_flat_range_product(copy(), pma2.release());
-  return manage(res);
+  return isl::checked::multi_pw_aff(*this).scale_down(mv);
 }
 
-stat pw_multi_aff::foreach_piece(const std::function<stat(isl::checked::set, isl::checked::multi_aff)> &fn) const
+isl::checked::pw_multi_aff pw_multi_aff::scale_down(isl::checked::val v) const
 {
-  struct fn_data {
-    std::function<stat(isl::checked::set, isl::checked::multi_aff)> func;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_set *arg_0, isl_multi_aff *arg_1, void *arg_2) -> isl_stat {
-    auto *data = static_cast<struct fn_data *>(arg_2);
-    auto ret = (data->func)(manage(arg_0), manage(arg_1));
-    return ret.release();
-  };
-  auto res = isl_pw_multi_aff_foreach_piece(get(), fn_lambda, &fn_data);
+  auto res = isl_pw_multi_aff_scale_down_val(copy(), v.release());
   return manage(res);
 }
 
-isl::checked::space pw_multi_aff::space() const
+isl::checked::pw_multi_aff pw_multi_aff::scale_down(long v) const
 {
-  auto res = isl_pw_multi_aff_get_space(get());
-  return manage(res);
+  return this->scale_down(isl::checked::val(ctx(), v));
 }
 
-isl::checked::space pw_multi_aff::get_space() const
+isl::checked::multi_pw_aff pw_multi_aff::set_at(int pos, const isl::checked::pw_aff &el) const
 {
-  return space();
+  return isl::checked::multi_pw_aff(*this).set_at(pos, el);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::gist(isl::checked::set set) const
+isl::checked::multi_union_pw_aff pw_multi_aff::set_at(int pos, const isl::checked::union_pw_aff &el) const
 {
-  auto res = isl_pw_multi_aff_gist(copy(), set.release());
-  return manage(res);
+  return isl::checked::multi_pw_aff(*this).set_at(pos, el);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::identity_on_domain(isl::checked::space space)
+isl::checked::pw_multi_aff pw_multi_aff::set_range_tuple(isl::checked::id id) const
 {
-  auto res = isl_pw_multi_aff_identity_on_domain_space(space.release());
+  auto res = isl_pw_multi_aff_set_range_tuple_id(copy(), id.release());
   return manage(res);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::insert_domain(isl::checked::space domain) const
+isl::checked::pw_multi_aff pw_multi_aff::set_range_tuple(const std::string &id) const
 {
-  auto res = isl_pw_multi_aff_insert_domain(copy(), domain.release());
-  return manage(res);
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::intersect_domain(isl::checked::set set) const
+class size pw_multi_aff::size() const
 {
-  auto res = isl_pw_multi_aff_intersect_domain(copy(), set.release());
+  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::pw_multi_aff pw_multi_aff::intersect_params(isl::checked::set set) const
+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
 {
-  auto res = isl_pw_multi_aff_intersect_params(copy(), set.release());
-  return manage(res);
+  return isl::checked::multi_pw_aff(*this).sub(multi2);
 }
 
-boolean pw_multi_aff::involves_locals() const
+isl::checked::multi_union_pw_aff pw_multi_aff::sub(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  auto res = isl_pw_multi_aff_involves_locals(get());
-  return manage(res);
+  return isl::checked::multi_pw_aff(*this).sub(multi2);
 }
 
-boolean pw_multi_aff::isa_multi_aff() const
+isl::checked::pw_multi_aff pw_multi_aff::sub(isl::checked::pw_multi_aff pma2) const
 {
-  auto res = isl_pw_multi_aff_isa_multi_aff(get());
+  auto res = isl_pw_multi_aff_sub(copy(), pma2.release());
   return manage(res);
 }
 
-isl::checked::multi_val pw_multi_aff::max_multi_val() const
+isl::checked::union_pw_multi_aff pw_multi_aff::sub(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_pw_multi_aff_max_multi_val(copy());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).sub(upma2);
 }
 
-isl::checked::multi_val pw_multi_aff::min_multi_val() const
+isl::checked::pw_multi_aff pw_multi_aff::sub(const isl::checked::multi_aff &pma2) const
 {
-  auto res = isl_pw_multi_aff_min_multi_val(copy());
-  return manage(res);
+  return this->sub(isl::checked::pw_multi_aff(pma2));
 }
 
-class size pw_multi_aff::n_piece() const
+isl::checked::pw_multi_aff pw_multi_aff::sub(const isl::checked::pw_aff &pma2) const
 {
-  auto res = isl_pw_multi_aff_n_piece(get());
-  return manage(res);
+  return this->sub(isl::checked::pw_multi_aff(pma2));
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(isl::checked::pw_multi_aff pma2) const
+isl::checked::pw_multi_aff pw_multi_aff::subtract_domain(isl::checked::set set) const
 {
-  auto res = isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(copy(), pma2.release());
+  auto res = isl_pw_multi_aff_subtract_domain(copy(), set.release());
   return manage(res);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::product(isl::checked::pw_multi_aff pma2) const
+isl::checked::union_pw_multi_aff pw_multi_aff::subtract_domain(const isl::checked::space &space) const
 {
-  auto res = isl_pw_multi_aff_product(copy(), pma2.release());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).subtract_domain(space);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::pullback(isl::checked::multi_aff ma) const
+isl::checked::union_pw_multi_aff pw_multi_aff::subtract_domain(const isl::checked::union_set &uset) const
 {
-  auto res = isl_pw_multi_aff_pullback_multi_aff(copy(), ma.release());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).subtract_domain(uset);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::pullback(isl::checked::pw_multi_aff pma2) const
+isl::checked::pw_multi_aff pw_multi_aff::subtract_domain(const isl::checked::basic_set &set) const
 {
-  auto res = isl_pw_multi_aff_pullback_pw_multi_aff(copy(), pma2.release());
-  return manage(res);
+  return this->subtract_domain(isl::checked::set(set));
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::range_factor_domain() const
+isl::checked::pw_multi_aff pw_multi_aff::subtract_domain(const isl::checked::point &set) const
 {
-  auto res = isl_pw_multi_aff_range_factor_domain(copy());
-  return manage(res);
+  return this->subtract_domain(isl::checked::set(set));
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::range_factor_range() const
+isl::checked::pw_multi_aff_list pw_multi_aff::to_list() const
 {
-  auto res = isl_pw_multi_aff_range_factor_range(copy());
+  auto res = isl_pw_multi_aff_to_list(copy());
   return manage(res);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::range_map(isl::checked::space space)
+isl::checked::multi_pw_aff pw_multi_aff::to_multi_pw_aff() const
 {
-  auto res = isl_pw_multi_aff_range_map(space.release());
+  auto res = isl_pw_multi_aff_to_multi_pw_aff(copy());
   return manage(res);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::range_product(isl::checked::pw_multi_aff pma2) const
+isl::checked::union_pw_multi_aff pw_multi_aff::to_union_pw_multi_aff() const
 {
-  auto res = isl_pw_multi_aff_range_product(copy(), pma2.release());
+  auto res = isl_pw_multi_aff_to_union_pw_multi_aff(copy());
   return manage(res);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::scale(isl::checked::val v) const
+isl::checked::multi_pw_aff pw_multi_aff::unbind_params_insert_domain(const isl::checked::multi_id &domain) const
 {
-  auto res = isl_pw_multi_aff_scale_val(copy(), v.release());
-  return manage(res);
+  return isl::checked::multi_pw_aff(*this).unbind_params_insert_domain(domain);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::scale(long v) const
+isl::checked::multi_pw_aff pw_multi_aff::union_add(const isl::checked::multi_pw_aff &mpa2) const
 {
-  return this->scale(isl::checked::val(ctx(), v));
+  return isl::checked::multi_pw_aff(*this).union_add(mpa2);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::scale_down(isl::checked::val v) const
+isl::checked::multi_union_pw_aff pw_multi_aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const
 {
-  auto res = isl_pw_multi_aff_scale_down_val(copy(), v.release());
-  return manage(res);
+  return isl::checked::multi_pw_aff(*this).union_add(mupa2);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::scale_down(long v) const
+isl::checked::pw_multi_aff pw_multi_aff::union_add(isl::checked::pw_multi_aff pma2) const
 {
-  return this->scale_down(isl::checked::val(ctx(), v));
+  auto res = isl_pw_multi_aff_union_add(copy(), pma2.release());
+  return manage(res);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::sub(isl::checked::pw_multi_aff pma2) const
+isl::checked::union_pw_multi_aff pw_multi_aff::union_add(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_pw_multi_aff_sub(copy(), pma2.release());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).union_add(upma2);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::subtract_domain(isl::checked::set set) const
+isl::checked::pw_multi_aff pw_multi_aff::union_add(const isl::checked::multi_aff &pma2) const
 {
-  auto res = isl_pw_multi_aff_subtract_domain(copy(), set.release());
-  return manage(res);
+  return this->union_add(isl::checked::pw_multi_aff(pma2));
 }
 
-isl::checked::pw_multi_aff pw_multi_aff::union_add(isl::checked::pw_multi_aff pma2) const
+isl::checked::pw_multi_aff pw_multi_aff::union_add(const isl::checked::pw_aff &pma2) const
 {
-  auto res = isl_pw_multi_aff_union_add(copy(), pma2.release());
-  return manage(res);
+  return this->union_add(isl::checked::pw_multi_aff(pma2));
 }
 
 isl::checked::pw_multi_aff pw_multi_aff::zero(isl::checked::space space)
@@ -8959,6 +14331,12 @@ pw_multi_aff_list::pw_multi_aff_list(isl::checked::pw_multi_aff el)
   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 @@ isl::checked::pw_multi_aff_list pw_multi_aff_list::add(isl::checked::pw_multi_af
   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 @@ stat pw_multi_aff_list::foreach(const std::function<stat(isl::checked::pw_multi_
   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 @@ isl::checked::ctx schedule::ctx() const {
   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 @@ isl::checked::union_set schedule::get_domain() const
   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 @@ isl::checked::union_map schedule::get_map() const
   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 @@ isl::checked::schedule_node schedule::get_root() const
   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 @@ isl::checked::ctx schedule_constraints::ctx() const {
   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 @@ isl::checked::union_map schedule_constraints::get_coincidence() const
   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,32 +14678,21 @@ isl::checked::union_set schedule_constraints::get_domain() const
   return domain();
 }
 
-isl::checked::union_map schedule_constraints::proximity() const
+isl::checked::schedule_constraints schedule_constraints::on_domain(isl::checked::union_set domain)
 {
-  auto res = isl_schedule_constraints_get_proximity(get());
+  auto res = isl_schedule_constraints_on_domain(domain.release());
   return manage(res);
 }
 
-isl::checked::union_map schedule_constraints::get_proximity() const
-{
-  return proximity();
-}
-
-isl::checked::union_map schedule_constraints::validity() const
+isl::checked::union_map schedule_constraints::proximity() const
 {
-  auto res = isl_schedule_constraints_get_validity(get());
+  auto res = isl_schedule_constraints_get_proximity(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)
+isl::checked::union_map schedule_constraints::get_proximity() const
 {
-  auto res = isl_schedule_constraints_on_domain(domain.release());
-  return manage(res);
+  return proximity();
 }
 
 isl::checked::schedule_constraints schedule_constraints::set_coincidence(isl::checked::union_map coincidence) const
@@ -9358,6 +14725,17 @@ isl::checked::schedule_constraints schedule_constraints::set_validity(isl::check
   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,72 +14827,6 @@ isl::checked::schedule_node schedule_node::ancestor(int generation) const
   return manage(res);
 }
 
-isl::checked::schedule_node schedule_node::child(int pos) const
-{
-  auto res = isl_schedule_node_child(copy(), pos);
-  return manage(res);
-}
-
-boolean schedule_node::every_descendant(const std::function<boolean(isl::checked::schedule_node)> &test) const
-{
-  struct test_data {
-    std::function<boolean(isl::checked::schedule_node)> func;
-  } test_data = { test };
-  auto test_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_bool {
-    auto *data = static_cast<struct test_data *>(arg_1);
-    auto ret = (data->func)(manage_copy(arg_0));
-    return ret.release();
-  };
-  auto res = isl_schedule_node_every_descendant(get(), test_lambda, &test_data);
-  return manage(res);
-}
-
-isl::checked::schedule_node schedule_node::first_child() const
-{
-  auto res = isl_schedule_node_first_child(copy());
-  return manage(res);
-}
-
-stat schedule_node::foreach_ancestor_top_down(const std::function<stat(isl::checked::schedule_node)> &fn) const
-{
-  struct fn_data {
-    std::function<stat(isl::checked::schedule_node)> func;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_stat {
-    auto *data = static_cast<struct fn_data *>(arg_1);
-    auto ret = (data->func)(manage_copy(arg_0));
-    return ret.release();
-  };
-  auto res = isl_schedule_node_foreach_ancestor_top_down(get(), fn_lambda, &fn_data);
-  return manage(res);
-}
-
-stat schedule_node::foreach_descendant_top_down(const std::function<boolean(isl::checked::schedule_node)> &fn) const
-{
-  struct fn_data {
-    std::function<boolean(isl::checked::schedule_node)> func;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_bool {
-    auto *data = static_cast<struct fn_data *>(arg_1);
-    auto ret = (data->func)(manage_copy(arg_0));
-    return ret.release();
-  };
-  auto res = isl_schedule_node_foreach_descendant_top_down(get(), fn_lambda, &fn_data);
-  return manage(res);
-}
-
-isl::checked::schedule_node schedule_node::from_domain(isl::checked::union_set domain)
-{
-  auto res = isl_schedule_node_from_domain(domain.release());
-  return manage(res);
-}
-
-isl::checked::schedule_node schedule_node::from_extension(isl::checked::union_map extension)
-{
-  auto res = isl_schedule_node_from_extension(extension.release());
-  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());
@@ -9522,85 +14834,85 @@ class size schedule_node::ancestor_child_position(const isl::checked::schedule_n
 }
 
 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);
+{
+  return ancestor_child_position(ancestor);
 }
 
-isl::checked::union_map schedule_node::get_prefix_schedule_union_map() const
+isl::checked::schedule_node schedule_node::child(int pos) const
 {
-  return prefix_schedule_union_map();
+  auto res = isl_schedule_node_child(copy(), pos);
+  return manage(res);
 }
 
-isl::checked::union_pw_multi_aff schedule_node::prefix_schedule_union_pw_multi_aff() const
+class size schedule_node::child_position() const
 {
-  auto res = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(get());
+  auto res = isl_schedule_node_get_child_position(get());
   return manage(res);
 }
 
-isl::checked::union_pw_multi_aff schedule_node::get_prefix_schedule_union_pw_multi_aff() const
+class size schedule_node::get_child_position() const
 {
-  return prefix_schedule_union_pw_multi_aff();
+  return child_position();
 }
 
-isl::checked::schedule schedule_node::schedule() const
+boolean schedule_node::every_descendant(const std::function<boolean(isl::checked::schedule_node)> &test) const
 {
-  auto res = isl_schedule_node_get_schedule(get());
+  struct test_data {
+    std::function<boolean(isl::checked::schedule_node)> func;
+  } test_data = { test };
+  auto test_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_bool {
+    auto *data = static_cast<struct test_data *>(arg_1);
+    auto ret = (data->func)(manage_copy(arg_0));
+    return ret.release();
+  };
+  auto res = isl_schedule_node_every_descendant(get(), test_lambda, &test_data);
   return manage(res);
 }
 
-isl::checked::schedule schedule_node::get_schedule() const
+isl::checked::schedule_node schedule_node::first_child() const
 {
-  return schedule();
+  auto res = isl_schedule_node_first_child(copy());
+  return manage(res);
 }
 
-isl::checked::schedule_node schedule_node::shared_ancestor(const isl::checked::schedule_node &node2) const
+stat schedule_node::foreach_ancestor_top_down(const std::function<stat(isl::checked::schedule_node)> &fn) const
 {
-  auto res = isl_schedule_node_get_shared_ancestor(get(), node2.get());
+  struct fn_data {
+    std::function<stat(isl::checked::schedule_node)> func;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_stat {
+    auto *data = static_cast<struct fn_data *>(arg_1);
+    auto ret = (data->func)(manage_copy(arg_0));
+    return ret.release();
+  };
+  auto res = isl_schedule_node_foreach_ancestor_top_down(get(), fn_lambda, &fn_data);
   return manage(res);
 }
 
-isl::checked::schedule_node schedule_node::get_shared_ancestor(const isl::checked::schedule_node &node2) const
+stat schedule_node::foreach_descendant_top_down(const std::function<boolean(isl::checked::schedule_node)> &fn) const
 {
-  return shared_ancestor(node2);
+  struct fn_data {
+    std::function<boolean(isl::checked::schedule_node)> func;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_bool {
+    auto *data = static_cast<struct fn_data *>(arg_1);
+    auto ret = (data->func)(manage_copy(arg_0));
+    return ret.release();
+  };
+  auto res = isl_schedule_node_foreach_descendant_top_down(get(), fn_lambda, &fn_data);
+  return manage(res);
 }
 
-class size schedule_node::tree_depth() const
+isl::checked::schedule_node schedule_node::from_domain(isl::checked::union_set domain)
 {
-  auto res = isl_schedule_node_get_tree_depth(get());
+  auto res = isl_schedule_node_from_domain(domain.release());
   return manage(res);
 }
 
-class size schedule_node::get_tree_depth() const
+isl::checked::schedule_node schedule_node::from_extension(isl::checked::union_map extension)
 {
-  return tree_depth();
+  auto res = isl_schedule_node_from_extension(extension.release());
+  return manage(res);
 }
 
 isl::checked::schedule_node schedule_node::graft_after(isl::checked::schedule_node graft) const
@@ -9742,6 +15054,39 @@ isl::checked::schedule_node schedule_node::parent() const
   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 @@ isl::checked::schedule_node schedule_node::root() const
   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,50 +15187,50 @@ isl::checked::set schedule_node_band::get_ast_isolate_option() const
   return ast_isolate_option();
 }
 
-isl::checked::multi_union_pw_aff schedule_node_band::partial_schedule() const
+boolean schedule_node_band::member_get_coincident(int pos) const
 {
-  auto res = isl_schedule_node_band_get_partial_schedule(get());
+  auto res = isl_schedule_node_band_member_get_coincident(get(), pos);
   return manage(res);
 }
 
-isl::checked::multi_union_pw_aff schedule_node_band::get_partial_schedule() const
+schedule_node_band schedule_node_band::member_set_coincident(int pos, int coincident) const
 {
-  return partial_schedule();
+  auto res = isl_schedule_node_band_member_set_coincident(copy(), pos, coincident);
+  return manage(res).as<schedule_node_band>();
 }
 
-boolean schedule_node_band::permutable() const
+schedule_node_band schedule_node_band::mod(isl::checked::multi_val mv) const
 {
-  auto res = isl_schedule_node_band_get_permutable(get());
-  return manage(res);
+  auto res = isl_schedule_node_band_mod(copy(), mv.release());
+  return manage(res).as<schedule_node_band>();
 }
 
-boolean schedule_node_band::get_permutable() const
+class size schedule_node_band::n_member() const
 {
-  return permutable();
+  auto res = isl_schedule_node_band_n_member(get());
+  return manage(res);
 }
 
-boolean schedule_node_band::member_get_coincident(int pos) const
+isl::checked::multi_union_pw_aff schedule_node_band::partial_schedule() const
 {
-  auto res = isl_schedule_node_band_member_get_coincident(get(), pos);
+  auto res = isl_schedule_node_band_get_partial_schedule(get());
   return manage(res);
 }
 
-schedule_node_band schedule_node_band::member_set_coincident(int pos, int coincident) const
+isl::checked::multi_union_pw_aff schedule_node_band::get_partial_schedule() const
 {
-  auto res = isl_schedule_node_band_member_set_coincident(copy(), pos, coincident);
-  return manage(res).as<schedule_node_band>();
+  return partial_schedule();
 }
 
-schedule_node_band schedule_node_band::mod(isl::checked::multi_val mv) const
+boolean schedule_node_band::permutable() const
 {
-  auto res = isl_schedule_node_band_mod(copy(), mv.release());
-  return manage(res).as<schedule_node_band>();
+  auto res = isl_schedule_node_band_get_permutable(get());
+  return manage(res);
 }
 
-class size schedule_node_band::n_member() const
+boolean schedule_node_band::get_permutable() const
 {
-  auto res = isl_schedule_node_band_n_member(get());
-  return manage(res);
+  return permutable();
 }
 
 schedule_node_band schedule_node_band::scale(isl::checked::multi_val mv) const
@@ -10423,6 +15801,27 @@ isl::checked::set set::apply(isl::checked::map map) const
   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 @@ isl::checked::set set::complement() const
   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 @@ isl::checked::set set::empty(isl::checked::space space)
   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,54 +15913,35 @@ stat set::foreach_point(const std::function<stat(isl::checked::point)> &fn) cons
   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::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
+stat set::foreach_set(const std::function<stat(isl::checked::set)> &fn) const
 {
-  return simple_fixed_box_hull();
+  return isl::checked::union_set(*this).foreach_set(fn);
 }
 
-isl::checked::space set::space() const
+isl::checked::set set::gist(isl::checked::set context) const
 {
-  auto res = isl_set_get_space(get());
+  auto res = isl_set_gist(copy(), context.release());
   return manage(res);
 }
 
-isl::checked::space set::get_space() const
+isl::checked::union_set set::gist(const isl::checked::union_set &context) const
 {
-  return space();
+  return isl::checked::union_set(*this).gist(context);
 }
 
-isl::checked::val set::stride(int pos) const
+isl::checked::set set::gist(const isl::checked::basic_set &context) const
 {
-  auto res = isl_set_get_stride(get(), pos);
-  return manage(res);
+  return this->gist(isl::checked::set(context));
 }
 
-isl::checked::val set::get_stride(int pos) const
+isl::checked::set set::gist(const isl::checked::point &context) const
 {
-  return stride(pos);
+  return this->gist(isl::checked::set(context));
 }
 
-isl::checked::set set::gist(isl::checked::set context) const
+isl::checked::union_set set::gist_params(const isl::checked::set &set) const
 {
-  auto res = isl_set_gist(copy(), context.release());
-  return manage(res);
+  return isl::checked::union_set(*this).gist_params(set);
 }
 
 isl::checked::map set::identity() const
@@ -10573,6 +15968,21 @@ isl::checked::set set::intersect(isl::checked::set set2) const
   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 @@ boolean set::is_disjoint(const isl::checked::set &set2) const
   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());
@@ -10599,8 +16024,23 @@ boolean set::is_empty() const
 
 boolean set::is_equal(const isl::checked::set &set2) const
 {
-  auto res = isl_set_is_equal(get(), set2.get());
-  return manage(res);
+  auto res = isl_set_is_equal(get(), set2.get());
+  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
@@ -10615,18 +16055,53 @@ boolean set::is_strict_subset(const isl::checked::set &set2) const
   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 @@ isl::checked::set set::params() const
   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 @@ isl::checked::set set::preimage(isl::checked::pw_multi_aff pma) const
   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 @@ isl::checked::set set::project_out_param(isl::checked::id_list list) const
   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 @@ isl::checked::point set::sample_point() const
   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 @@ isl::checked::set set::unite(isl::checked::set set2) const
   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 @@ isl::checked::space space::add_named_tuple(const std::string &tuple_id, unsigned
   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);
@@ -10908,91 +16496,278 @@ isl::checked::space space::curry() const
 
 isl::checked::space space::domain() const
 {
-  auto res = isl_space_domain(copy());
+  auto res = isl_space_domain(copy());
+  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());
+  return manage(res);
+}
+
+isl::checked::space space::flatten_range() const
+{
+  auto res = isl_space_flatten_range(copy());
+  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());
+  return manage(res);
+}
+
+boolean space::is_wrapping() const
+{
+  auto res = isl_space_is_wrapping(get());
+  return manage(res);
+}
+
+isl::checked::space space::map_from_set() const
+{
+  auto res = isl_space_map_from_set(copy());
+  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());
+  return manage(res);
+}
+
+isl::checked::space space::product(isl::checked::space right) const
+{
+  auto res = isl_space_product(copy(), right.release());
+  return manage(res);
+}
+
+isl::checked::space space::range() const
+{
+  auto res = isl_space_range(copy());
+  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::flatten_domain() const
+isl::checked::space space::set_domain_tuple(const std::string &id) const
 {
-  auto res = isl_space_flatten_domain(copy());
-  return manage(res);
+  return this->set_domain_tuple(isl::checked::id(ctx(), id));
 }
 
-isl::checked::space space::flatten_range() const
+isl::checked::space space::set_range_tuple(isl::checked::id id) const
 {
-  auto res = isl_space_flatten_range(copy());
+  auto res = isl_space_set_range_tuple_id(copy(), id.release());
   return manage(res);
 }
 
-boolean space::is_equal(const isl::checked::space &space2) const
+isl::checked::space space::set_range_tuple(const std::string &id) const
 {
-  auto res = isl_space_is_equal(get(), space2.get());
-  return manage(res);
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
 }
 
-boolean space::is_wrapping() const
+isl::checked::space space::uncurry() const
 {
-  auto res = isl_space_is_wrapping(get());
+  auto res = isl_space_uncurry(copy());
   return manage(res);
 }
 
-isl::checked::space space::map_from_set() const
+isl::checked::space space::unit(isl::checked::ctx ctx)
 {
-  auto res = isl_space_map_from_set(copy());
+  auto res = isl_space_unit(ctx.release());
   return manage(res);
 }
 
-isl::checked::space space::params() const
+isl::checked::map space::universe_map() const
 {
-  auto res = isl_space_params(copy());
+  auto res = isl_space_universe_map(copy());
   return manage(res);
 }
 
-isl::checked::space space::product(isl::checked::space right) const
+isl::checked::set space::universe_set() const
 {
-  auto res = isl_space_product(copy(), right.release());
+  auto res = isl_space_universe_set(copy());
   return manage(res);
 }
 
-isl::checked::space space::range() const
+isl::checked::space space::unwrap() const
 {
-  auto res = isl_space_range(copy());
+  auto res = isl_space_unwrap(copy());
   return manage(res);
 }
 
-isl::checked::space space::range_reverse() const
+isl::checked::space space::wrap() const
 {
-  auto res = isl_space_range_reverse(copy());
+  auto res = isl_space_wrap(copy());
   return manage(res);
 }
 
-isl::checked::space space::reverse() const
+isl::checked::aff space::zero_aff_on_domain() const
 {
-  auto res = isl_space_reverse(copy());
+  auto res = isl_space_zero_aff_on_domain(copy());
   return manage(res);
 }
 
-isl::checked::space space::uncurry() const
+isl::checked::multi_aff space::zero_multi_aff() const
 {
-  auto res = isl_space_uncurry(copy());
+  auto res = isl_space_zero_multi_aff(copy());
   return manage(res);
 }
 
-isl::checked::space space::unit(isl::checked::ctx ctx)
+isl::checked::multi_pw_aff space::zero_multi_pw_aff() const
 {
-  auto res = isl_space_unit(ctx.release());
+  auto res = isl_space_zero_multi_pw_aff(copy());
   return manage(res);
 }
 
-isl::checked::space space::unwrap() const
+isl::checked::multi_union_pw_aff space::zero_multi_union_pw_aff() const
 {
-  auto res = isl_space_unwrap(copy());
+  auto res = isl_space_zero_multi_union_pw_aff(copy());
   return manage(res);
 }
 
-isl::checked::space space::wrap() const
+isl::checked::multi_val space::zero_multi_val() const
 {
-  auto res = isl_space_wrap(copy());
+  auto res = isl_space_zero_multi_val(copy());
   return manage(res);
 }
 
@@ -11335,6 +17110,24 @@ isl::checked::union_map union_map::apply_range(isl::checked::union_map umap2) co
   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 @@ isl::checked::union_map union_map::from_range(isl::checked::union_set uset)
   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 @@ isl::checked::union_map union_map::lexmin() const
   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 @@ isl::checked::union_map union_map::reverse() const
   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());
@@ -11892,41 +17696,278 @@ __isl_give isl_union_pw_aff *union_pw_aff::release() {
   return tmp;
 }
 
-bool union_pw_aff::is_null() const {
-  return ptr == nullptr;
+bool union_pw_aff::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::checked::ctx union_pw_aff::ctx() const {
+  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());
+  return manage(res);
+}
+
+isl::checked::union_set union_pw_aff::bind(const std::string &id) const
+{
+  return this->bind(isl::checked::id(ctx(), id));
+}
+
+isl::checked::union_pw_aff union_pw_aff::coalesce() const
+{
+  auto res = isl_union_pw_aff_coalesce(copy());
+  return manage(res);
+}
+
+isl::checked::union_set union_pw_aff::domain() const
+{
+  auto res = isl_union_pw_aff_domain(copy());
+  return manage(res);
+}
+
+isl::checked::pw_multi_aff union_pw_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_union_pw_aff union_pw_aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  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
+{
+  auto res = isl_union_pw_aff_gist(copy(), context.release());
+  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());
+  return manage(res);
+}
+
+isl::checked::union_pw_aff union_pw_aff::intersect_domain(isl::checked::union_set uset) const
+{
+  auto res = isl_union_pw_aff_intersect_domain_union_set(copy(), uset.release());
+  return manage(res);
+}
+
+isl::checked::union_pw_aff union_pw_aff::intersect_domain_wrapped_domain(isl::checked::union_set uset) const
+{
+  auto res = isl_union_pw_aff_intersect_domain_wrapped_domain(copy(), uset.release());
+  return manage(res);
+}
+
+isl::checked::union_pw_aff union_pw_aff::intersect_domain_wrapped_range(isl::checked::union_set uset) const
+{
+  auto res = isl_union_pw_aff_intersect_domain_wrapped_range(copy(), uset.release());
+  return manage(res);
+}
+
+isl::checked::union_pw_aff union_pw_aff::intersect_params(isl::checked::set set) const
+{
+  auto res = isl_union_pw_aff_intersect_params(copy(), set.release());
+  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::ctx union_pw_aff::ctx() const {
-  return isl::checked::ctx(isl_union_pw_aff_get_ctx(ptr));
+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::union_pw_aff union_pw_aff::add(isl::checked::union_pw_aff upa2) const
+isl::checked::multi_union_pw_aff union_pw_aff::scale_down(long v) const
 {
-  auto res = isl_union_pw_aff_add(copy(), upa2.release());
-  return manage(res);
+  return this->scale_down(isl::checked::val(ctx(), v));
 }
 
-isl::checked::union_set union_pw_aff::bind(isl::checked::id id) const
+isl::checked::multi_union_pw_aff union_pw_aff::set_at(int pos, const isl::checked::union_pw_aff &el) const
 {
-  auto res = isl_union_pw_aff_bind_id(copy(), id.release());
-  return manage(res);
+  return isl::checked::multi_union_pw_aff(*this).set_at(pos, el);
 }
 
-isl::checked::union_set union_pw_aff::bind(const std::string &id) const
+isl::checked::multi_union_pw_aff union_pw_aff::set_range_tuple(const isl::checked::id &id) const
 {
-  return this->bind(isl::checked::id(ctx(), id));
+  return isl::checked::multi_union_pw_aff(*this).set_range_tuple(id);
 }
 
-isl::checked::union_pw_aff union_pw_aff::coalesce() const
+isl::checked::multi_union_pw_aff union_pw_aff::set_range_tuple(const std::string &id) const
 {
-  auto res = isl_union_pw_aff_coalesce(copy());
-  return manage(res);
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
 }
 
-isl::checked::union_set union_pw_aff::domain() const
+class size union_pw_aff::size() const
 {
-  auto res = isl_union_pw_aff_domain(copy());
-  return manage(res);
+  return isl::checked::multi_union_pw_aff(*this).size();
 }
 
 isl::checked::space union_pw_aff::space() const
@@ -11940,70 +17981,74 @@ isl::checked::space union_pw_aff::get_space() const
   return space();
 }
 
-isl::checked::union_pw_aff union_pw_aff::gist(isl::checked::union_set context) const
+isl::checked::multi_union_pw_aff union_pw_aff::sub(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  auto res = isl_union_pw_aff_gist(copy(), context.release());
-  return manage(res);
+  return isl::checked::multi_union_pw_aff(*this).sub(multi2);
 }
 
-isl::checked::union_pw_aff union_pw_aff::intersect_domain(isl::checked::space space) const
+isl::checked::union_pw_aff union_pw_aff::sub(isl::checked::union_pw_aff upa2) const
 {
-  auto res = isl_union_pw_aff_intersect_domain_space(copy(), space.release());
+  auto res = isl_union_pw_aff_sub(copy(), upa2.release());
   return manage(res);
 }
 
-isl::checked::union_pw_aff union_pw_aff::intersect_domain(isl::checked::union_set uset) const
+isl::checked::union_pw_multi_aff union_pw_aff::sub(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_union_pw_aff_intersect_domain_union_set(copy(), uset.release());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).sub(upma2);
 }
 
-isl::checked::union_pw_aff union_pw_aff::intersect_domain_wrapped_domain(isl::checked::union_set uset) const
+isl::checked::union_pw_aff union_pw_aff::sub(const isl::checked::aff &upa2) const
 {
-  auto res = isl_union_pw_aff_intersect_domain_wrapped_domain(copy(), uset.release());
-  return manage(res);
+  return this->sub(isl::checked::union_pw_aff(upa2));
 }
 
-isl::checked::union_pw_aff union_pw_aff::intersect_domain_wrapped_range(isl::checked::union_set uset) const
+isl::checked::union_pw_aff union_pw_aff::sub(const isl::checked::pw_aff &upa2) const
 {
-  auto res = isl_union_pw_aff_intersect_domain_wrapped_range(copy(), uset.release());
-  return manage(res);
+  return this->sub(isl::checked::union_pw_aff(upa2));
 }
 
-isl::checked::union_pw_aff union_pw_aff::intersect_params(isl::checked::set set) const
+isl::checked::union_pw_aff union_pw_aff::subtract_domain(isl::checked::space space) const
 {
-  auto res = isl_union_pw_aff_intersect_params(copy(), set.release());
+  auto res = isl_union_pw_aff_subtract_domain_space(copy(), space.release());
   return manage(res);
 }
 
-isl::checked::union_pw_aff union_pw_aff::pullback(isl::checked::union_pw_multi_aff upma) const
+isl::checked::union_pw_aff union_pw_aff::subtract_domain(isl::checked::union_set uset) const
 {
-  auto res = isl_union_pw_aff_pullback_union_pw_multi_aff(copy(), upma.release());
+  auto res = isl_union_pw_aff_subtract_domain_union_set(copy(), uset.release());
   return manage(res);
 }
 
-isl::checked::union_pw_aff union_pw_aff::sub(isl::checked::union_pw_aff upa2) const
+isl::checked::union_pw_aff_list union_pw_aff::to_list() const
 {
-  auto res = isl_union_pw_aff_sub(copy(), upa2.release());
+  auto res = isl_union_pw_aff_to_list(copy());
   return manage(res);
 }
 
-isl::checked::union_pw_aff union_pw_aff::subtract_domain(isl::checked::space space) const
+isl::checked::multi_union_pw_aff union_pw_aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const
 {
-  auto res = isl_union_pw_aff_subtract_domain_space(copy(), space.release());
-  return manage(res);
+  return isl::checked::multi_union_pw_aff(*this).union_add(mupa2);
 }
 
-isl::checked::union_pw_aff union_pw_aff::subtract_domain(isl::checked::union_set uset) const
+isl::checked::union_pw_aff union_pw_aff::union_add(isl::checked::union_pw_aff upa2) const
 {
-  auto res = isl_union_pw_aff_subtract_domain_union_set(copy(), uset.release());
+  auto res = isl_union_pw_aff_union_add(copy(), upa2.release());
   return manage(res);
 }
 
-isl::checked::union_pw_aff union_pw_aff::union_add(isl::checked::union_pw_aff upa2) const
+isl::checked::union_pw_multi_aff union_pw_aff::union_add(const isl::checked::union_pw_multi_aff &upma2) const
 {
-  auto res = isl_union_pw_aff_union_add(copy(), upa2.release());
-  return manage(res);
+  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)
@@ -12051,6 +18096,12 @@ union_pw_aff_list::union_pw_aff_list(isl::checked::union_pw_aff el)
   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 @@ isl::checked::union_pw_aff_list union_pw_aff_list::add(isl::checked::union_pw_af
   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 @@ stat union_pw_aff_list::foreach(const std::function<stat(isl::checked::union_pw_
   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 @@ isl::checked::union_pw_multi_aff union_pw_multi_aff::apply(isl::checked::union_p
   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 @@ isl::checked::union_pw_multi_aff union_pw_multi_aff::flat_range_product(isl::che
   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 @@ isl::checked::union_pw_multi_aff union_pw_multi_aff::pullback(isl::checked::unio
   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 @@ isl::checked::union_pw_multi_aff union_pw_multi_aff::range_product(isl::checked:
   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 @@ isl::checked::union_set union_set::apply(isl::checked::union_map umap) const
   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 @@ stat union_set::foreach_set(const std::function<stat(isl::checked::set)> &fn) co
   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 @@ isl::checked::point union_set::sample_point() const
   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 @@ union_set_list::union_set_list(isl::checked::union_set el)
   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 @@ isl::checked::union_set_list union_set_list::add(isl::checked::union_set el) con
   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 @@ stat union_set_list::foreach(const std::function<stat(isl::checked::union_set)>
   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 @@ int val::cmp_si(long i) const
   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 @@ boolean val::ge(long v2) const
   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 @@ isl::checked::val val::negone(isl::checked::ctx ctx)
   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 @@ isl::checked::val val::sub(long v2) const
   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 @@ val_list::val_list(isl::checked::val el)
   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 @@ isl::checked::val_list val_list::add(long el) const
   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 @@ stat val_list::foreach(const std::function<stat(isl::checked::val)> &fn) const
   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/polly/lib/External/isl/include/isl/cpp.h b/polly/lib/External/isl/include/isl/cpp.h
index 147cc055498a2..f47b12a97790d 100644
--- a/polly/lib/External/isl/include/isl/cpp.h
+++ b/polly/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 @@ class options_scoped_set_on_error {
 
 } // 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 fixed_box;
 class id;
 class id_list;
 class map;
+class map_list;
 class multi_aff;
 class multi_id;
 class multi_pw_aff;
@@ -382,35 +383,158 @@ class aff {
   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::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::val constant_val() const;
-  inline isl::val get_constant_val() 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 @@ class aff_list {
   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 @@ class aff_list {
   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 @@ class ast_build {
   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 @@ class ast_node {
   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 @@ class ast_node_for : public ast_node {
   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 @@ class ast_node_if : public ast_node {
   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 @@ class ast_node_list {
   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 @@ class basic_map {
 
   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 @@ class basic_set {
 
   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 @@ class fixed_box {
   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 @@ class id {
 
   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 @@ class id_list {
   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 @@ class id_list {
 
   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 @@ class map {
 
   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 @@ class map {
   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 @@ class map {
   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 @@ class multi_aff {
   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;
+  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::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 isl::aff at(int pos) const;
-  inline isl::aff get_at(int pos) 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 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 @@ class multi_aff {
   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 @@ class multi_id {
   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 @@ class multi_pw_aff {
   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 @@ class multi_pw_aff {
   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::multi_pw_aff sub(isl::multi_pw_aff multi2) 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 @@ class multi_union_pw_aff {
   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 @@ class multi_union_pw_aff {
   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 @@ class multi_val {
   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 @@ class multi_val {
   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 @@ class point {
   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 @@ class pw_aff {
   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 @@ class pw_aff {
   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 @@ class pw_aff_list {
   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 @@ class pw_aff_list {
   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 @@ class pw_multi_aff {
   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 @@ class pw_multi_aff_list {
   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 @@ class pw_multi_aff_list {
   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 @@ class schedule {
   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 @@ class schedule_constraints {
   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 @@ class schedule_constraints {
   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 @@ class schedule_node {
   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 @@ class schedule_node {
   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 @@ class schedule_node_band : public schedule_node {
   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 @@ class set {
 
   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 @@ class set {
   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 @@ class space {
 
   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 @@ class union_map {
   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 @@ class union_map {
   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 @@ class union_map {
   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 @@ class union_map {
   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 @@ class union_pw_aff {
   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 @@ class union_pw_aff_list {
   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 @@ class union_pw_aff_list {
   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 @@ class union_pw_multi_aff {
 
   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 @@ class union_pw_multi_aff {
   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 @@ class union_set {
 
   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 @@ class union_set {
   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 @@ class union_set {
   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 @@ class union_set_list {
   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 @@ class union_set_list {
   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 @@ class val {
   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 @@ class val {
   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 @@ class val {
   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 @@ class val_list {
   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 @@ class val_list {
 
   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,12 +4389,61 @@ isl::aff aff::add(isl::aff aff2) const
   return manage(res);
 }
 
-isl::aff aff::add_constant(isl::val v) const
+isl::multi_aff aff::add(const isl::multi_aff &multi2) const
 {
-  if (!ptr || v.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);
+  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())
+    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_add_constant_val(copy(), v.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
@@ -3399,6 +4457,76 @@ isl::aff aff::add_constant(long v) const
   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,76 +4546,58 @@ isl::basic_set aff::bind(const std::string &id) const
   return this->bind(isl::id(ctx(), id));
 }
 
-isl::aff aff::ceil() const
+isl::basic_set aff::bind(const isl::multi_id &tuple) 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_ceil(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_aff(*this).bind(tuple);
 }
 
-isl::aff aff::div(isl::aff aff2) const
+isl::pw_aff aff::bind_domain(const isl::multi_id &tuple) 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_div(copy(), aff2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_aff(*this).bind_domain(tuple);
 }
 
-isl::set aff::eq_set(isl::aff aff2) const
+isl::pw_aff aff::bind_domain_wrapped_domain(const isl::multi_id &tuple) 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_eq_set(copy(), aff2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_aff(*this).bind_domain_wrapped_domain(tuple);
 }
 
-isl::val aff::eval(isl::point pnt) const
+isl::aff aff::ceil() const
 {
-  if (!ptr || pnt.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_eval(copy(), pnt.release());
+  auto res = isl_aff_ceil(copy());
   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,1134 +4617,979 @@ isl::val aff::get_constant_val() const
   return constant_val();
 }
 
-isl::aff aff::gist(isl::set context) const
+isl::aff aff::div(isl::aff aff2) const
 {
-  if (!ptr || context.is_null())
+  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_gist(copy(), context.release());
+  auto res = isl_aff_div(copy(), aff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set aff::gt_set(isl::aff aff2) const
+isl::pw_aff aff::div(const isl::pw_aff &pa2) 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_gt_set(copy(), aff2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_aff(*this).div(pa2);
 }
 
-bool aff::is_cst() const
+isl::set aff::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_aff_is_cst(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::pw_aff(*this).domain();
 }
 
-isl::set aff::le_set(isl::aff aff2) const
+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_le_set(copy(), aff2.release());
+  auto res = isl_aff_eq_set(copy(), aff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set aff::lt_set(isl::aff aff2) const
+isl::set aff::eq_set(const isl::pw_aff &pwaff2) 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_lt_set(copy(), aff2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_aff(*this).eq_set(pwaff2);
 }
 
-isl::aff aff::mod(isl::val mod) const
+isl::val aff::eval(isl::point pnt) const
 {
-  if (!ptr || mod.is_null())
+  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_mod_val(copy(), mod.release());
+  auto res = isl_aff_eval(copy(), pnt.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::aff aff::mod(long mod) const
+isl::pw_multi_aff aff::extract_pw_multi_aff(const isl::space &space) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->mod(isl::val(ctx(), mod));
+  return isl::pw_aff(*this).extract_pw_multi_aff(space);
 }
 
-isl::aff aff::mul(isl::aff aff2) const
+isl::multi_aff aff::flat_range_product(const isl::multi_aff &multi2) 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_mul(copy(), aff2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_aff(*this).flat_range_product(multi2);
 }
 
-isl::set aff::ne_set(isl::aff aff2) const
+isl::multi_pw_aff aff::flat_range_product(const isl::multi_pw_aff &multi2) 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_ne_set(copy(), aff2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_aff(*this).flat_range_product(multi2);
 }
 
-isl::aff aff::neg() const
+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__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_aff_neg(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_aff(*this).flat_range_product(multi2);
 }
 
-isl::aff aff::pullback(isl::multi_aff ma) const
+isl::pw_multi_aff aff::flat_range_product(const isl::pw_multi_aff &pma2) const
 {
-  if (!ptr || ma.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_pullback_multi_aff(copy(), ma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_aff(*this).flat_range_product(pma2);
 }
 
-isl::aff aff::scale(isl::val v) const
+isl::union_pw_multi_aff aff::flat_range_product(const isl::union_pw_multi_aff &upma2) const
 {
-  if (!ptr || v.is_null())
+  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_scale_val(copy(), v.release());
+  auto res = isl_aff_floor(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::aff aff::scale(long v) const
+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 this->scale(isl::val(ctx(), v));
+  return isl::pw_aff(*this).foreach_piece(fn);
 }
 
-isl::aff aff::scale_down(isl::val v) const
+isl::set aff::ge_set(isl::aff aff2) const
 {
-  if (!ptr || v.is_null())
+  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_scale_down_val(copy(), v.release());
+  auto res = isl_aff_ge_set(copy(), aff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::aff aff::scale_down(long v) const
+isl::set aff::ge_set(const isl::pw_aff &pwaff2) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->scale_down(isl::val(ctx(), v));
+  return isl::pw_aff(*this).ge_set(pwaff2);
 }
 
-isl::aff aff::sub(isl::aff aff2) const
+isl::aff aff::gist(isl::set context) const
 {
-  if (!ptr || aff2.is_null())
+  if (!ptr || context.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_sub(copy(), aff2.release());
+  auto res = isl_aff_gist(copy(), context.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::aff aff::unbind_params_insert_domain(isl::multi_id domain) const
+isl::union_pw_aff aff::gist(const isl::union_set &context) const
 {
-  if (!ptr || domain.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_unbind_params_insert_domain(copy(), domain.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_aff(*this).gist(context);
 }
 
-isl::aff aff::zero_on_domain(isl::space space)
+isl::aff aff::gist(const isl::basic_set &context) const
 {
-  if (space.is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
+  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())
+    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_zero_on_domain_space(space.release());
+  auto res = isl_aff_gt_set(copy(), aff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const aff &obj)
+isl::set aff::gt_set(const isl::pw_aff &pwaff2) const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_aff_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_aff_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return isl::pw_aff(*this).gt_set(pwaff2);
 }
 
-// implementations for isl::aff_list
-aff_list manage(__isl_take isl_aff_list *ptr) {
+bool aff::has_range_tuple_id() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return aff_list(ptr);
+  return isl::multi_aff(*this).has_range_tuple_id();
 }
-aff_list manage_copy(__isl_keep isl_aff_list *ptr) {
+
+isl::multi_aff aff::identity() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_aff_list_get_ctx(ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_aff_list_copy(ptr);
-  if (!ptr)
-    exception::throw_last_error(saved_ctx);
-  return aff_list(ptr);
+  return isl::multi_aff(*this).identity();
 }
 
-aff_list::aff_list()
-    : ptr(nullptr) {}
-
-aff_list::aff_list(const aff_list &obj)
-    : ptr(nullptr)
+isl::pw_aff aff::insert_domain(const isl::space &domain) const
 {
-  if (!obj.ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_aff_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);
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).insert_domain(domain);
 }
 
-aff_list::aff_list(__isl_take isl_aff_list *ptr)
-    : ptr(ptr) {}
-
-aff_list::aff_list(isl::ctx ctx, int n)
+isl::pw_aff aff::intersect_domain(const isl::set &set) const
 {
-  auto saved_ctx = ctx;
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_aff_list_alloc(ctx.release(), n);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).intersect_domain(set);
 }
 
-aff_list::aff_list(isl::aff el)
+isl::union_pw_aff aff::intersect_domain(const isl::space &space) const
 {
-  if (el.is_null())
+  if (!ptr)
     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_aff_list_from_aff(el.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return isl::pw_aff(*this).intersect_domain(space);
 }
 
-aff_list &aff_list::operator=(aff_list obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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);
 }
 
-aff_list::~aff_list() {
-  if (ptr)
-    isl_aff_list_free(ptr);
+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_give isl_aff_list *aff_list::copy() const & {
-  return isl_aff_list_copy(ptr);
+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_keep isl_aff_list *aff_list::get() const {
-  return ptr;
+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);
 }
 
-__isl_give isl_aff_list *aff_list::release() {
-  isl_aff_list *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+bool aff::involves_locals() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).involves_locals();
 }
 
-bool aff_list::is_null() const {
-  return ptr == nullptr;
+bool aff::involves_nan() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).involves_nan();
 }
 
-isl::ctx aff_list::ctx() const {
-  return isl::ctx(isl_aff_list_get_ctx(ptr));
+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);
 }
 
-isl::aff_list aff_list::add(isl::aff el) const
+bool aff::involves_param(const std::string &id) const
 {
-  if (!ptr || el.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_list_add(copy(), el.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->involves_param(isl::id(ctx(), id));
 }
 
-isl::aff_list aff_list::clear() const
+bool aff::involves_param(const isl::id_list &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_list_clear(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_aff(*this).involves_param(list);
 }
 
-isl::aff_list aff_list::concat(isl::aff_list list2) const
+bool aff::is_cst() const
 {
-  if (!ptr || list2.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_list_concat(copy(), list2.release());
-  if (!res)
+  auto res = isl_aff_is_cst(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::aff_list aff_list::drop(unsigned int first, unsigned int n) const
+bool aff::isa_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_aff_list_drop(copy(), first, n);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_aff(*this).isa_aff();
 }
 
-void aff_list::foreach(const std::function<void(isl::aff)> &fn) const
+bool 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);
-  struct fn_data {
-    std::function<void(isl::aff)> func;
-    std::exception_ptr eptr;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_aff *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_aff_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;
+  return isl::pw_aff(*this).isa_multi_aff();
 }
 
-isl::aff aff_list::at(int index) const
+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())
+    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);
+  auto res = isl_aff_le_set(copy(), aff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::aff aff_list::get_at(int index) const
+isl::set aff::le_set(const isl::pw_aff &pwaff2) const
 {
-  return at(index);
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).le_set(pwaff2);
 }
 
-isl::aff_list aff_list::insert(unsigned int pos, isl::aff el) const
+isl::aff_list aff::list() const
 {
-  if (!ptr || el.is_null())
+  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())
     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_insert(copy(), pos, el.release());
+  auto res = isl_aff_lt_set(copy(), aff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-unsigned aff_list::size() const
+isl::set aff::lt_set(const isl::pw_aff &pwaff2) 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_size(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::pw_aff(*this).lt_set(pwaff2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const aff_list &obj)
+isl::multi_pw_aff aff::max(const isl::multi_pw_aff &multi2) const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_aff_list_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_aff_list_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return isl::pw_aff(*this).max(multi2);
 }
 
-// implementations for isl::ast_build
-ast_build manage(__isl_take isl_ast_build *ptr) {
+isl::pw_aff aff::max(const isl::pw_aff &pwaff2) const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return ast_build(ptr);
+  return isl::pw_aff(*this).max(pwaff2);
 }
-ast_build manage_copy(__isl_keep isl_ast_build *ptr) {
+
+isl::multi_val aff::max_multi_val() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_build_get_ctx(ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_ast_build_copy(ptr);
-  if (!ptr)
-    exception::throw_last_error(saved_ctx);
-  return ast_build(ptr);
+  return isl::pw_aff(*this).max_multi_val();
 }
 
-ast_build::ast_build()
-    : ptr(nullptr) {}
-
-ast_build::ast_build(const ast_build &obj)
-    : ptr(nullptr)
+isl::multi_pw_aff aff::min(const isl::multi_pw_aff &multi2) const
 {
-  if (!obj.ptr)
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_build_get_ctx(obj.ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = obj.copy();
-  copy_callbacks(obj);
+  return isl::pw_aff(*this).min(multi2);
+}
+
+isl::pw_aff aff::min(const isl::pw_aff &pwaff2) const
+{
   if (!ptr)
-    exception::throw_last_error(saved_ctx);
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).min(pwaff2);
 }
 
-ast_build::ast_build(__isl_take isl_ast_build *ptr)
-    : ptr(ptr) {}
+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();
+}
 
-ast_build::ast_build(isl::ctx ctx)
+isl::aff aff::mod(isl::val mod) const
 {
-  auto saved_ctx = ctx;
+  if (!ptr || mod.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_ast_build_alloc(ctx.release());
+  auto res = isl_aff_mod_val(copy(), mod.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-ast_build &ast_build::operator=(ast_build obj) {
-  std::swap(this->ptr, obj.ptr);
-  copy_callbacks(obj);
-  return *this;
-}
-
-ast_build::~ast_build() {
-  if (ptr)
-    isl_ast_build_free(ptr);
-}
-
-__isl_give isl_ast_build *ast_build::copy() const & {
-  return isl_ast_build_copy(ptr);
-}
-
-__isl_keep isl_ast_build *ast_build::get() const {
-  return ptr;
-}
-
-__isl_give isl_ast_build *ast_build::release() {
-  if (at_each_domain_data)
-    exception::throw_invalid("cannot release object with persistent callbacks", __FILE__, __LINE__);
-  isl_ast_build *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
-}
-
-bool ast_build::is_null() const {
-  return ptr == nullptr;
-}
-
-isl::ctx ast_build::ctx() const {
-  return isl::ctx(isl_ast_build_get_ctx(ptr));
-}
-
-ast_build &ast_build::copy_callbacks(const ast_build &obj)
+isl::aff aff::mod(long mod) const
 {
-  at_each_domain_data = obj.at_each_domain_data;
-  return *this;
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->mod(isl::val(ctx(), mod));
 }
 
-isl_ast_node *ast_build::at_each_domain(isl_ast_node *arg_0, isl_ast_build *arg_1, void *arg_2)
+isl::aff aff::mul(isl::aff aff2) const
 {
-  auto *data = static_cast<struct at_each_domain_data *>(arg_2);
-  ISL_CPP_TRY {
-    auto ret = (data->func)(manage(arg_0), manage_copy(arg_1));
-    return ret.release();
-  } ISL_CPP_CATCH_ALL {
-    data->eptr = std::current_exception();
-    return NULL;
-  }
+  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_mul(copy(), aff2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-void ast_build::set_at_each_domain_data(const std::function<isl::ast_node(isl::ast_node, isl::ast_build)> &fn)
+isl::pw_aff aff::mul(const isl::pw_aff &pwaff2) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_build_get_ctx(ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  at_each_domain_data = std::make_shared<struct at_each_domain_data>();
-  at_each_domain_data->func = fn;
-  ptr = isl_ast_build_set_at_each_domain(ptr, &at_each_domain, at_each_domain_data.get());
-  if (!ptr)
-    exception::throw_last_error(saved_ctx);
+  return isl::pw_aff(*this).mul(pwaff2);
 }
 
-isl::ast_build ast_build::set_at_each_domain(const std::function<isl::ast_node(isl::ast_node, isl::ast_build)> &fn) const
+unsigned aff::n_piece() const
 {
-  auto copy = *this;
-  copy.set_at_each_domain_data(fn);
-  return copy;
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).n_piece();
 }
 
-isl::ast_expr ast_build::access_from(isl::multi_pw_aff mpa) const
+isl::set aff::ne_set(isl::aff aff2) const
 {
-  if (!ptr || mpa.is_null())
+  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_ast_build_access_from_multi_pw_aff(get(), mpa.release());
-  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);
-  }
+  auto res = isl_aff_ne_set(copy(), aff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_expr ast_build::access_from(isl::pw_multi_aff pma) const
+isl::set aff::ne_set(const isl::pw_aff &pwaff2) const
 {
-  if (!ptr || pma.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_ast_build_access_from_pw_multi_aff(get(), pma.release());
-  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);
+  return isl::pw_aff(*this).ne_set(pwaff2);
 }
 
-isl::ast_expr ast_build::call_from(isl::multi_pw_aff mpa) const
+isl::aff aff::neg() const
 {
-  if (!ptr || mpa.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_ast_build_call_from_multi_pw_aff(get(), mpa.release());
-  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);
-  }
+  auto res = isl_aff_neg(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_expr ast_build::call_from(isl::pw_multi_aff pma) const
+bool aff::plain_is_empty() const
 {
-  if (!ptr || pma.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_ast_build_call_from_pw_multi_aff(get(), pma.release());
-  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);
+  return isl::pw_aff(*this).plain_is_empty();
 }
 
-isl::ast_expr ast_build::expr_from(isl::pw_aff pa) const
+bool aff::plain_is_equal(const isl::multi_aff &multi2) const
 {
-  if (!ptr || pa.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_ast_build_expr_from_pw_aff(get(), pa.release());
-  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);
+  return isl::multi_aff(*this).plain_is_equal(multi2);
 }
 
-isl::ast_expr ast_build::expr_from(isl::set set) const
+bool aff::plain_is_equal(const isl::multi_pw_aff &multi2) const
 {
-  if (!ptr || set.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_ast_build_expr_from_set(get(), set.release());
-  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);
+  return isl::pw_aff(*this).plain_is_equal(multi2);
 }
 
-isl::ast_build ast_build::from_context(isl::set set)
+bool aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const
 {
-  if (set.is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = set.ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_ast_build_from_context(set.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_aff(*this).plain_is_equal(multi2);
 }
 
-isl::union_map ast_build::schedule() const
+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__);
-  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);
+  return isl::pw_aff(*this).preimage_domain_wrapped_domain(pma2);
 }
 
-isl::union_map ast_build::get_schedule() const
+isl::union_pw_multi_aff aff::preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const
 {
-  return schedule();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).preimage_domain_wrapped_domain(upma2);
 }
 
-isl::ast_node ast_build::node_from(isl::schedule schedule) const
+isl::multi_aff aff::product(const isl::multi_aff &multi2) const
 {
-  if (!ptr || schedule.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_ast_build_node_from_schedule(get(), schedule.release());
-  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);
+  return isl::multi_aff(*this).product(multi2);
 }
 
-isl::ast_node ast_build::node_from_schedule_map(isl::union_map schedule) const
+isl::multi_pw_aff aff::product(const isl::multi_pw_aff &multi2) const
 {
-  if (!ptr || schedule.is_null())
+  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())
     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_node_from_schedule_map(get(), schedule.release());
-  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);
-  }
+  auto res = isl_aff_pullback_multi_aff(copy(), ma.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-// implementations for isl::ast_expr
-ast_expr manage(__isl_take isl_ast_expr *ptr) {
+isl::pw_aff aff::pullback(const isl::multi_pw_aff &mpa) const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return ast_expr(ptr);
+  return isl::pw_aff(*this).pullback(mpa);
 }
-ast_expr manage_copy(__isl_keep isl_ast_expr *ptr) {
+
+isl::pw_aff aff::pullback(const isl::pw_multi_aff &pma) const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_ast_expr_copy(ptr);
-  if (!ptr)
-    exception::throw_last_error(saved_ctx);
-  return ast_expr(ptr);
+  return isl::pw_aff(*this).pullback(pma);
 }
 
-ast_expr::ast_expr()
-    : ptr(nullptr) {}
-
-ast_expr::ast_expr(const ast_expr &obj)
-    : ptr(nullptr)
+isl::union_pw_aff aff::pullback(const isl::union_pw_multi_aff &upma) const
 {
-  if (!obj.ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_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);
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).pullback(upma);
 }
 
-ast_expr::ast_expr(__isl_take isl_ast_expr *ptr)
-    : ptr(ptr) {}
-
-ast_expr &ast_expr::operator=(ast_expr obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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));
 }
 
-ast_expr::~ast_expr() {
-  if (ptr)
-    isl_ast_expr_free(ptr);
+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_give isl_ast_expr *ast_expr::copy() const & {
-  return isl_ast_expr_copy(ptr);
+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_keep isl_ast_expr *ast_expr::get() const {
-  return ptr;
+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_give isl_ast_expr *ast_expr::release() {
-  isl_ast_expr *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+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);
 }
 
-bool ast_expr::is_null() const {
-  return ptr == nullptr;
+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);
 }
 
-template <typename T, typename>
-bool ast_expr::isa_type(T subtype) const
+isl::multi_union_pw_aff aff::range_product(const isl::multi_union_pw_aff &multi2) const
 {
-  if (is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return isl_ast_expr_get_type(get()) == subtype;
+  return isl::pw_aff(*this).range_product(multi2);
 }
-template <class T>
-bool ast_expr::isa() const
+
+isl::pw_multi_aff aff::range_product(const isl::pw_multi_aff &pma2) const
 {
-  return isa_type<decltype(T::type)>(T::type);
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).range_product(pma2);
 }
-template <class T>
-T ast_expr::as() const
+
+isl::union_pw_multi_aff aff::range_product(const isl::union_pw_multi_aff &upma2) const
 {
- if (!isa<T>())
-    exception::throw_invalid("not an object of the requested subtype", __FILE__, __LINE__);
-  return T(copy());
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).range_product(upma2);
 }
 
-isl::ctx ast_expr::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+isl::id aff::range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).range_tuple_id();
 }
 
-std::string ast_expr::to_C_str() const
+isl::multi_aff 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_ast_expr_to_C_str(get());
-  std::string tmp(res);
-  free(res);
-  return tmp;
+  return isl::multi_aff(*this).reset_range_tuple_id();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr &obj)
+isl::aff aff::scale(isl::val v) const
 {
-  if (!obj.get())
+  if (!ptr || v.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  auto res = isl_aff_scale_val(copy(), v.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::ast_expr_id
-ast_expr_id::ast_expr_id()
-    : ast_expr() {}
-
-ast_expr_id::ast_expr_id(const ast_expr_id &obj)
-    : ast_expr(obj)
+isl::aff aff::scale(long v) const
 {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->scale(isl::val(ctx(), v));
 }
 
-ast_expr_id::ast_expr_id(__isl_take isl_ast_expr *ptr)
-    : ast_expr(ptr) {}
-
-ast_expr_id &ast_expr_id::operator=(ast_expr_id obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx ast_expr_id::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+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::id ast_expr_id::id() const
+isl::aff aff::scale_down(isl::val v) const
 {
-  if (!ptr)
+  if (!ptr || v.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_ast_expr_id_get_id(get());
+  auto res = isl_aff_scale_down_val(copy(), v.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::id ast_expr_id::get_id() const
+isl::aff aff::scale_down(long v) const
 {
-  return id();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->scale_down(isl::val(ctx(), v));
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_id &obj)
+isl::multi_aff aff::scale_down(const isl::multi_val &mv) const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return isl::multi_aff(*this).scale_down(mv);
 }
 
-// implementations for isl::ast_expr_int
-ast_expr_int::ast_expr_int()
-    : ast_expr() {}
+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);
+}
 
-ast_expr_int::ast_expr_int(const ast_expr_int &obj)
-    : ast_expr(obj)
+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);
 }
 
-ast_expr_int::ast_expr_int(__isl_take isl_ast_expr *ptr)
-    : ast_expr(ptr) {}
+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);
+}
 
-ast_expr_int &ast_expr_int::operator=(ast_expr_int obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_int::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+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));
 }
 
-isl::val ast_expr_int::val() const
+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())
+    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_expr_int_get_val(get());
+  auto res = isl_aff_sub(copy(), aff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::val ast_expr_int::get_val() const
+isl::multi_aff aff::sub(const isl::multi_aff &multi2) const
 {
-  return val();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).sub(multi2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_int &obj)
+isl::multi_pw_aff aff::sub(const isl::multi_pw_aff &multi2) const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return isl::pw_aff(*this).sub(multi2);
 }
 
-// implementations for isl::ast_expr_op
-ast_expr_op::ast_expr_op()
-    : ast_expr() {}
+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);
+}
 
-ast_expr_op::ast_expr_op(const ast_expr_op &obj)
-    : ast_expr(obj)
+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);
 }
 
-ast_expr_op::ast_expr_op(__isl_take isl_ast_expr *ptr)
-    : ast_expr(ptr) {}
+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);
+}
 
-ast_expr_op &ast_expr_op::operator=(ast_expr_op obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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);
 }
 
-template <typename T, typename>
-bool ast_expr_op::isa_type(T subtype) const
+isl::union_pw_multi_aff aff::sub(const isl::union_pw_multi_aff &upma2) const
 {
-  if (is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return isl_ast_expr_op_get_type(get()) == subtype;
+  return isl::pw_aff(*this).sub(upma2);
 }
-template <class T>
-bool ast_expr_op::isa() const
+
+isl::pw_aff aff::subtract_domain(const isl::set &set) const
 {
-  return isa_type<decltype(T::type)>(T::type);
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).subtract_domain(set);
 }
-template <class T>
-T ast_expr_op::as() const
+
+isl::union_pw_aff aff::subtract_domain(const isl::space &space) const
 {
- if (!isa<T>())
-    exception::throw_invalid("not an object of the requested subtype", __FILE__, __LINE__);
-  return T(copy());
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).subtract_domain(space);
 }
 
-isl::ctx ast_expr_op::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+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::ast_expr ast_expr_op::arg(int pos) const
+isl::pw_aff aff::tdiv_q(const isl::pw_aff &pa2) 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_expr_op_get_arg(get(), pos);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_aff(*this).tdiv_q(pa2);
 }
 
-isl::ast_expr ast_expr_op::get_arg(int pos) const
+isl::pw_aff aff::tdiv_r(const isl::pw_aff &pa2) const
 {
-  return arg(pos);
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).tdiv_r(pa2);
 }
 
-unsigned ast_expr_op::n_arg() const
+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_ast_expr_op_get_n_arg(get());
-  if (res < 0)
+  auto res = isl_aff_to_list(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-unsigned ast_expr_op::get_n_arg() const
+isl::multi_pw_aff aff::to_multi_pw_aff() const
 {
-  return n_arg();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).to_multi_pw_aff();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op &obj)
+isl::multi_union_pw_aff aff::to_multi_union_pw_aff() const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return isl::multi_aff(*this).to_multi_union_pw_aff();
 }
 
-// implementations for isl::ast_expr_op_access
-ast_expr_op_access::ast_expr_op_access()
-    : ast_expr_op() {}
+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();
+}
 
-ast_expr_op_access::ast_expr_op_access(const ast_expr_op_access &obj)
-    : ast_expr_op(obj)
+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();
 }
 
-ast_expr_op_access::ast_expr_op_access(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_access &ast_expr_op_access::operator=(ast_expr_op_access obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx ast_expr_op_access::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+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();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_access &obj)
+isl::aff aff::unbind_params_insert_domain(isl::multi_id domain) const
 {
-  if (!obj.get())
+  if (!ptr || domain.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  auto res = isl_aff_unbind_params_insert_domain(copy(), domain.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::ast_expr_op_add
-ast_expr_op_add::ast_expr_op_add()
-    : ast_expr_op() {}
-
-ast_expr_op_add::ast_expr_op_add(const ast_expr_op_add &obj)
-    : ast_expr_op(obj)
+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);
 }
 
-ast_expr_op_add::ast_expr_op_add(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_add &ast_expr_op_add::operator=(ast_expr_op_add obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_op_add::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+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);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_add &obj)
+isl::pw_multi_aff aff::union_add(const isl::pw_multi_aff &pma2) const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return isl::pw_aff(*this).union_add(pma2);
 }
 
-// implementations for isl::ast_expr_op_address_of
-ast_expr_op_address_of::ast_expr_op_address_of()
-    : ast_expr_op() {}
-
-ast_expr_op_address_of::ast_expr_op_address_of(const ast_expr_op_address_of &obj)
-    : ast_expr_op(obj)
+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);
 }
 
-ast_expr_op_address_of::ast_expr_op_address_of(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_address_of &ast_expr_op_address_of::operator=(ast_expr_op_address_of obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_op_address_of::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+isl::aff aff::zero_on_domain(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_aff_zero_on_domain_space(space.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_address_of &obj)
+inline std::ostream &operator<<(std::ostream &os, const aff &obj)
 {
   if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = isl_aff_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
+  char *str = isl_aff_to_str(obj.get());
   if (!str)
     exception::throw_last_error(saved_ctx);
   os << str;
@@ -4642,209 +5597,229 @@ inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_address_of &
   return os;
 }
 
-// implementations for isl::ast_expr_op_and
-ast_expr_op_and::ast_expr_op_and()
-    : ast_expr_op() {}
-
-ast_expr_op_and::ast_expr_op_and(const ast_expr_op_and &obj)
-    : ast_expr_op(obj)
-{
+// implementations for isl::aff_list
+aff_list manage(__isl_take isl_aff_list *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return aff_list(ptr);
 }
-
-ast_expr_op_and::ast_expr_op_and(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_and &ast_expr_op_and::operator=(ast_expr_op_and obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+aff_list manage_copy(__isl_keep isl_aff_list *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_aff_list_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_aff_list_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return aff_list(ptr);
 }
 
-isl::ctx ast_expr_op_and::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
-}
+aff_list::aff_list()
+    : ptr(nullptr) {}
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_and &obj)
+aff_list::aff_list(const aff_list &obj)
+    : ptr(nullptr)
 {
-  if (!obj.get())
+  if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = isl_aff_list_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  ptr = obj.copy();
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
 }
 
-// implementations for isl::ast_expr_op_and_then
-ast_expr_op_and_then::ast_expr_op_and_then()
-    : ast_expr_op() {}
+aff_list::aff_list(__isl_take isl_aff_list *ptr)
+    : ptr(ptr) {}
 
-ast_expr_op_and_then::ast_expr_op_and_then(const ast_expr_op_and_then &obj)
-    : ast_expr_op(obj)
+aff_list::aff_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_aff_list_alloc(ctx.release(), n);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
 }
 
-ast_expr_op_and_then::ast_expr_op_and_then(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_and_then &ast_expr_op_and_then::operator=(ast_expr_op_and_then obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx ast_expr_op_and_then::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
-}
-
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_and_then &obj)
+aff_list::aff_list(isl::aff el)
 {
-  if (!obj.get())
+  if (el.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = el.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  auto res = isl_aff_list_from_aff(el.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  ptr = res;
 }
 
-// implementations for isl::ast_expr_op_call
-ast_expr_op_call::ast_expr_op_call()
-    : ast_expr_op() {}
-
-ast_expr_op_call::ast_expr_op_call(const ast_expr_op_call &obj)
-    : ast_expr_op(obj)
+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;
 }
 
-ast_expr_op_call::ast_expr_op_call(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_call &ast_expr_op_call::operator=(ast_expr_op_call obj) {
+aff_list &aff_list::operator=(aff_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-isl::ctx ast_expr_op_call::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+aff_list::~aff_list() {
+  if (ptr)
+    isl_aff_list_free(ptr);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_call &obj)
-{
-  if (!obj.get())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+__isl_give isl_aff_list *aff_list::copy() const & {
+  return isl_aff_list_copy(ptr);
 }
 
-// implementations for isl::ast_expr_op_cond
-ast_expr_op_cond::ast_expr_op_cond()
-    : ast_expr_op() {}
-
-ast_expr_op_cond::ast_expr_op_cond(const ast_expr_op_cond &obj)
-    : ast_expr_op(obj)
-{
+__isl_keep isl_aff_list *aff_list::get() const {
+  return ptr;
 }
 
-ast_expr_op_cond::ast_expr_op_cond(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+__isl_give isl_aff_list *aff_list::release() {
+  isl_aff_list *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
 
-ast_expr_op_cond &ast_expr_op_cond::operator=(ast_expr_op_cond obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+bool aff_list::is_null() const {
+  return ptr == nullptr;
 }
 
-isl::ctx ast_expr_op_cond::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+isl::ctx aff_list::ctx() const {
+  return isl::ctx(isl_aff_list_get_ctx(ptr));
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_cond &obj)
+isl::aff_list aff_list::add(isl::aff el) const
 {
-  if (!obj.get())
+  if (!ptr || el.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  auto res = isl_aff_list_add(copy(), el.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::ast_expr_op_div
-ast_expr_op_div::ast_expr_op_div()
-    : ast_expr_op() {}
-
-ast_expr_op_div::ast_expr_op_div(const ast_expr_op_div &obj)
-    : ast_expr_op(obj)
+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);
 }
 
-ast_expr_op_div::ast_expr_op_div(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_div &ast_expr_op_div::operator=(ast_expr_op_div obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::aff aff_list::get_at(int index) const
+{
+  return at(index);
 }
 
-isl::ctx ast_expr_op_div::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+isl::aff_list aff_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_aff_list_clear(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_div &obj)
+isl::aff_list aff_list::concat(isl::aff_list list2) const
 {
-  if (!obj.get())
+  if (!ptr || list2.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  auto res = isl_aff_list_concat(copy(), list2.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::ast_expr_op_eq
-ast_expr_op_eq::ast_expr_op_eq()
-    : ast_expr_op() {}
-
-ast_expr_op_eq::ast_expr_op_eq(const ast_expr_op_eq &obj)
-    : ast_expr_op(obj)
+isl::aff_list aff_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_aff_list_drop(copy(), first, n);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-ast_expr_op_eq::ast_expr_op_eq(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+void aff_list::foreach(const std::function<void(isl::aff)> &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::aff)> func;
+    std::exception_ptr eptr;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_aff *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_aff_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;
+}
 
-ast_expr_op_eq &ast_expr_op_eq::operator=(ast_expr_op_eq obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::aff_list aff_list::insert(unsigned int pos, isl::aff 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_aff_list_insert(copy(), pos, el.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::ctx ast_expr_op_eq::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+unsigned aff_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_aff_list_size(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_eq &obj)
+inline std::ostream &operator<<(std::ostream &os, const aff_list &obj)
 {
   if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = isl_aff_list_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
+  char *str = isl_aff_list_to_str(obj.get());
   if (!str)
     exception::throw_last_error(saved_ctx);
   os << str;
@@ -4852,139 +5827,7969 @@ inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_eq &obj)
   return os;
 }
 
-// implementations for isl::ast_expr_op_fdiv_q
-ast_expr_op_fdiv_q::ast_expr_op_fdiv_q()
-    : ast_expr_op() {}
-
-ast_expr_op_fdiv_q::ast_expr_op_fdiv_q(const ast_expr_op_fdiv_q &obj)
-    : ast_expr_op(obj)
-{
+// implementations for isl::ast_build
+ast_build manage(__isl_take isl_ast_build *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return ast_build(ptr);
 }
-
-ast_expr_op_fdiv_q::ast_expr_op_fdiv_q(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_fdiv_q &ast_expr_op_fdiv_q::operator=(ast_expr_op_fdiv_q obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+ast_build manage_copy(__isl_keep isl_ast_build *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_build_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_ast_build_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return ast_build(ptr);
 }
 
-isl::ctx ast_expr_op_fdiv_q::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
-}
+ast_build::ast_build()
+    : ptr(nullptr) {}
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_fdiv_q &obj)
+ast_build::ast_build(const ast_build &obj)
+    : ptr(nullptr)
 {
-  if (!obj.get())
+  if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = isl_ast_build_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  ptr = obj.copy();
+  copy_callbacks(obj);
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
 }
 
-// implementations for isl::ast_expr_op_ge
-ast_expr_op_ge::ast_expr_op_ge()
-    : ast_expr_op() {}
+ast_build::ast_build(__isl_take isl_ast_build *ptr)
+    : ptr(ptr) {}
 
-ast_expr_op_ge::ast_expr_op_ge(const ast_expr_op_ge &obj)
-    : ast_expr_op(obj)
+ast_build::ast_build(isl::ctx ctx)
 {
+  auto saved_ctx = ctx;
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_ast_build_alloc(ctx.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
 }
 
-ast_expr_op_ge::ast_expr_op_ge(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_ge &ast_expr_op_ge::operator=(ast_expr_op_ge obj) {
+ast_build &ast_build::operator=(ast_build obj) {
   std::swap(this->ptr, obj.ptr);
+  copy_callbacks(obj);
   return *this;
 }
 
-isl::ctx ast_expr_op_ge::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+ast_build::~ast_build() {
+  if (ptr)
+    isl_ast_build_free(ptr);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_ge &obj)
-{
-  if (!obj.get())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+__isl_give isl_ast_build *ast_build::copy() const & {
+  return isl_ast_build_copy(ptr);
 }
 
-// implementations for isl::ast_expr_op_gt
-ast_expr_op_gt::ast_expr_op_gt()
-    : ast_expr_op() {}
+__isl_keep isl_ast_build *ast_build::get() const {
+  return ptr;
+}
 
-ast_expr_op_gt::ast_expr_op_gt(const ast_expr_op_gt &obj)
-    : ast_expr_op(obj)
-{
+__isl_give isl_ast_build *ast_build::release() {
+  if (at_each_domain_data)
+    exception::throw_invalid("cannot release object with persistent callbacks", __FILE__, __LINE__);
+  isl_ast_build *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
 }
 
-ast_expr_op_gt::ast_expr_op_gt(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+bool ast_build::is_null() const {
+  return ptr == nullptr;
+}
 
-ast_expr_op_gt &ast_expr_op_gt::operator=(ast_expr_op_gt obj) {
-  std::swap(this->ptr, obj.ptr);
+isl::ctx ast_build::ctx() const {
+  return isl::ctx(isl_ast_build_get_ctx(ptr));
+}
+
+ast_build &ast_build::copy_callbacks(const ast_build &obj)
+{
+  at_each_domain_data = obj.at_each_domain_data;
   return *this;
 }
 
-isl::ctx ast_expr_op_gt::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+isl_ast_node *ast_build::at_each_domain(isl_ast_node *arg_0, isl_ast_build *arg_1, void *arg_2)
+{
+  auto *data = static_cast<struct at_each_domain_data *>(arg_2);
+  ISL_CPP_TRY {
+    auto ret = (data->func)(manage(arg_0), manage_copy(arg_1));
+    return ret.release();
+  } ISL_CPP_CATCH_ALL {
+    data->eptr = std::current_exception();
+    return NULL;
+  }
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_gt &obj)
+void ast_build::set_at_each_domain_data(const std::function<isl::ast_node(isl::ast_node, isl::ast_build)> &fn)
 {
-  if (!obj.get())
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_build_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  at_each_domain_data = std::make_shared<struct at_each_domain_data>();
+  at_each_domain_data->func = fn;
+  ptr = isl_ast_build_set_at_each_domain(ptr, &at_each_domain, at_each_domain_data.get());
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+}
+
+isl::ast_build ast_build::set_at_each_domain(const std::function<isl::ast_node(isl::ast_node, isl::ast_build)> &fn) const
+{
+  auto copy = *this;
+  copy.set_at_each_domain_data(fn);
+  return copy;
+}
+
+isl::ast_expr ast_build::access_from(isl::multi_pw_aff mpa) const
+{
+  if (!ptr || mpa.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_ast_build_access_from_multi_pw_aff(get(), mpa.release());
+  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::ast_expr ast_build::access_from(isl::pw_multi_aff pma) const
+{
+  if (!ptr || pma.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_ast_build_access_from_pw_multi_aff(get(), pma.release());
+  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::ast_expr ast_build::call_from(isl::multi_pw_aff mpa) const
+{
+  if (!ptr || mpa.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_ast_build_call_from_multi_pw_aff(get(), mpa.release());
+  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::ast_expr ast_build::call_from(isl::pw_multi_aff pma) const
+{
+  if (!ptr || pma.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_ast_build_call_from_pw_multi_aff(get(), pma.release());
+  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::ast_expr ast_build::expr_from(isl::pw_aff pa) const
+{
+  if (!ptr || pa.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_ast_build_expr_from_pw_aff(get(), pa.release());
+  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::ast_expr ast_build::expr_from(isl::set set) const
+{
+  if (!ptr || set.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_ast_build_expr_from_set(get(), set.release());
+  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::ast_build ast_build::from_context(isl::set set)
+{
+  if (set.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = set.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_ast_build_from_context(set.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_node ast_build::node_from(isl::schedule schedule) const
+{
+  if (!ptr || schedule.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_ast_build_node_from_schedule(get(), schedule.release());
+  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::ast_node ast_build::node_from_schedule_map(isl::union_map schedule) const
+{
+  if (!ptr || schedule.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_ast_build_node_from_schedule_map(get(), schedule.release());
+  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::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)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return ast_expr(ptr);
+}
+ast_expr manage_copy(__isl_keep isl_ast_expr *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_ast_expr_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return ast_expr(ptr);
+}
+
+ast_expr::ast_expr()
+    : ptr(nullptr) {}
+
+ast_expr::ast_expr(const ast_expr &obj)
+    : ptr(nullptr)
+{
+  if (!obj.ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_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);
+}
+
+ast_expr::ast_expr(__isl_take isl_ast_expr *ptr)
+    : ptr(ptr) {}
+
+ast_expr &ast_expr::operator=(ast_expr obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+ast_expr::~ast_expr() {
+  if (ptr)
+    isl_ast_expr_free(ptr);
+}
+
+__isl_give isl_ast_expr *ast_expr::copy() const & {
+  return isl_ast_expr_copy(ptr);
+}
+
+__isl_keep isl_ast_expr *ast_expr::get() const {
+  return ptr;
+}
+
+__isl_give isl_ast_expr *ast_expr::release() {
+  isl_ast_expr *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool ast_expr::is_null() const {
+  return ptr == nullptr;
+}
+
+template <typename T, typename>
+bool ast_expr::isa_type(T subtype) const
+{
+  if (is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl_ast_expr_get_type(get()) == subtype;
+}
+template <class T>
+bool ast_expr::isa() const
+{
+  return isa_type<decltype(T::type)>(T::type);
+}
+template <class T>
+T ast_expr::as() const
+{
+ if (!isa<T>())
+    exception::throw_invalid("not an object of the requested subtype", __FILE__, __LINE__);
+  return T(copy());
+}
+
+isl::ctx ast_expr::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+std::string ast_expr::to_C_str() 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_expr_to_C_str(get());
+  std::string tmp(res);
+  free(res);
+  return tmp;
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_id
+ast_expr_id::ast_expr_id()
+    : ast_expr() {}
+
+ast_expr_id::ast_expr_id(const ast_expr_id &obj)
+    : ast_expr(obj)
+{
+}
+
+ast_expr_id::ast_expr_id(__isl_take isl_ast_expr *ptr)
+    : ast_expr(ptr) {}
+
+ast_expr_id &ast_expr_id::operator=(ast_expr_id obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_id::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+isl::id ast_expr_id::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_ast_expr_id_get_id(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id ast_expr_id::get_id() const
+{
+  return id();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_id &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_int
+ast_expr_int::ast_expr_int()
+    : ast_expr() {}
+
+ast_expr_int::ast_expr_int(const ast_expr_int &obj)
+    : ast_expr(obj)
+{
+}
+
+ast_expr_int::ast_expr_int(__isl_take isl_ast_expr *ptr)
+    : ast_expr(ptr) {}
+
+ast_expr_int &ast_expr_int::operator=(ast_expr_int obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_int::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+isl::val ast_expr_int::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_ast_expr_int_get_val(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::val ast_expr_int::get_val() const
+{
+  return val();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_int &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op
+ast_expr_op::ast_expr_op()
+    : ast_expr() {}
+
+ast_expr_op::ast_expr_op(const ast_expr_op &obj)
+    : ast_expr(obj)
+{
+}
+
+ast_expr_op::ast_expr_op(__isl_take isl_ast_expr *ptr)
+    : ast_expr(ptr) {}
+
+ast_expr_op &ast_expr_op::operator=(ast_expr_op obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+template <typename T, typename>
+bool ast_expr_op::isa_type(T subtype) const
+{
+  if (is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl_ast_expr_op_get_type(get()) == subtype;
+}
+template <class T>
+bool ast_expr_op::isa() const
+{
+  return isa_type<decltype(T::type)>(T::type);
+}
+template <class T>
+T ast_expr_op::as() const
+{
+ if (!isa<T>())
+    exception::throw_invalid("not an object of the requested subtype", __FILE__, __LINE__);
+  return T(copy());
+}
+
+isl::ctx ast_expr_op::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+isl::ast_expr ast_expr_op::arg(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_ast_expr_op_get_arg(get(), pos);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_expr ast_expr_op::get_arg(int pos) const
+{
+  return arg(pos);
+}
+
+unsigned ast_expr_op::n_arg() 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_expr_op_get_n_arg(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+unsigned ast_expr_op::get_n_arg() const
+{
+  return n_arg();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_access
+ast_expr_op_access::ast_expr_op_access()
+    : ast_expr_op() {}
+
+ast_expr_op_access::ast_expr_op_access(const ast_expr_op_access &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_access::ast_expr_op_access(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_access &ast_expr_op_access::operator=(ast_expr_op_access obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_access::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_access &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_add
+ast_expr_op_add::ast_expr_op_add()
+    : ast_expr_op() {}
+
+ast_expr_op_add::ast_expr_op_add(const ast_expr_op_add &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_add::ast_expr_op_add(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_add &ast_expr_op_add::operator=(ast_expr_op_add obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_add::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_add &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_address_of
+ast_expr_op_address_of::ast_expr_op_address_of()
+    : ast_expr_op() {}
+
+ast_expr_op_address_of::ast_expr_op_address_of(const ast_expr_op_address_of &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_address_of::ast_expr_op_address_of(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_address_of &ast_expr_op_address_of::operator=(ast_expr_op_address_of obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_address_of::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_address_of &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_and
+ast_expr_op_and::ast_expr_op_and()
+    : ast_expr_op() {}
+
+ast_expr_op_and::ast_expr_op_and(const ast_expr_op_and &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_and::ast_expr_op_and(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_and &ast_expr_op_and::operator=(ast_expr_op_and obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_and::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_and &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_and_then
+ast_expr_op_and_then::ast_expr_op_and_then()
+    : ast_expr_op() {}
+
+ast_expr_op_and_then::ast_expr_op_and_then(const ast_expr_op_and_then &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_and_then::ast_expr_op_and_then(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_and_then &ast_expr_op_and_then::operator=(ast_expr_op_and_then obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_and_then::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_and_then &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_call
+ast_expr_op_call::ast_expr_op_call()
+    : ast_expr_op() {}
+
+ast_expr_op_call::ast_expr_op_call(const ast_expr_op_call &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_call::ast_expr_op_call(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_call &ast_expr_op_call::operator=(ast_expr_op_call obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_call::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_call &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_cond
+ast_expr_op_cond::ast_expr_op_cond()
+    : ast_expr_op() {}
+
+ast_expr_op_cond::ast_expr_op_cond(const ast_expr_op_cond &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_cond::ast_expr_op_cond(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_cond &ast_expr_op_cond::operator=(ast_expr_op_cond obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_cond::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_cond &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_div
+ast_expr_op_div::ast_expr_op_div()
+    : ast_expr_op() {}
+
+ast_expr_op_div::ast_expr_op_div(const ast_expr_op_div &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_div::ast_expr_op_div(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_div &ast_expr_op_div::operator=(ast_expr_op_div obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_div::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_div &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_eq
+ast_expr_op_eq::ast_expr_op_eq()
+    : ast_expr_op() {}
+
+ast_expr_op_eq::ast_expr_op_eq(const ast_expr_op_eq &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_eq::ast_expr_op_eq(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_eq &ast_expr_op_eq::operator=(ast_expr_op_eq obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_eq::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_eq &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_fdiv_q
+ast_expr_op_fdiv_q::ast_expr_op_fdiv_q()
+    : ast_expr_op() {}
+
+ast_expr_op_fdiv_q::ast_expr_op_fdiv_q(const ast_expr_op_fdiv_q &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_fdiv_q::ast_expr_op_fdiv_q(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_fdiv_q &ast_expr_op_fdiv_q::operator=(ast_expr_op_fdiv_q obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_fdiv_q::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_fdiv_q &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_ge
+ast_expr_op_ge::ast_expr_op_ge()
+    : ast_expr_op() {}
+
+ast_expr_op_ge::ast_expr_op_ge(const ast_expr_op_ge &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_ge::ast_expr_op_ge(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_ge &ast_expr_op_ge::operator=(ast_expr_op_ge obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_ge::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_ge &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_gt
+ast_expr_op_gt::ast_expr_op_gt()
+    : ast_expr_op() {}
+
+ast_expr_op_gt::ast_expr_op_gt(const ast_expr_op_gt &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_gt::ast_expr_op_gt(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_gt &ast_expr_op_gt::operator=(ast_expr_op_gt obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_gt::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_gt &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_le
+ast_expr_op_le::ast_expr_op_le()
+    : ast_expr_op() {}
+
+ast_expr_op_le::ast_expr_op_le(const ast_expr_op_le &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_le::ast_expr_op_le(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_le &ast_expr_op_le::operator=(ast_expr_op_le obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_le::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_le &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_lt
+ast_expr_op_lt::ast_expr_op_lt()
+    : ast_expr_op() {}
+
+ast_expr_op_lt::ast_expr_op_lt(const ast_expr_op_lt &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_lt::ast_expr_op_lt(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_lt &ast_expr_op_lt::operator=(ast_expr_op_lt obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_lt::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_lt &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_max
+ast_expr_op_max::ast_expr_op_max()
+    : ast_expr_op() {}
+
+ast_expr_op_max::ast_expr_op_max(const ast_expr_op_max &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_max::ast_expr_op_max(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_max &ast_expr_op_max::operator=(ast_expr_op_max obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_max::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_max &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_member
+ast_expr_op_member::ast_expr_op_member()
+    : ast_expr_op() {}
+
+ast_expr_op_member::ast_expr_op_member(const ast_expr_op_member &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_member::ast_expr_op_member(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_member &ast_expr_op_member::operator=(ast_expr_op_member obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_member::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_member &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_min
+ast_expr_op_min::ast_expr_op_min()
+    : ast_expr_op() {}
+
+ast_expr_op_min::ast_expr_op_min(const ast_expr_op_min &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_min::ast_expr_op_min(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_min &ast_expr_op_min::operator=(ast_expr_op_min obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_min::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_min &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_minus
+ast_expr_op_minus::ast_expr_op_minus()
+    : ast_expr_op() {}
+
+ast_expr_op_minus::ast_expr_op_minus(const ast_expr_op_minus &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_minus::ast_expr_op_minus(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_minus &ast_expr_op_minus::operator=(ast_expr_op_minus obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_minus::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_minus &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_mul
+ast_expr_op_mul::ast_expr_op_mul()
+    : ast_expr_op() {}
+
+ast_expr_op_mul::ast_expr_op_mul(const ast_expr_op_mul &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_mul::ast_expr_op_mul(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_mul &ast_expr_op_mul::operator=(ast_expr_op_mul obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_mul::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_mul &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_or
+ast_expr_op_or::ast_expr_op_or()
+    : ast_expr_op() {}
+
+ast_expr_op_or::ast_expr_op_or(const ast_expr_op_or &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_or::ast_expr_op_or(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_or &ast_expr_op_or::operator=(ast_expr_op_or obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_or::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_or &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_or_else
+ast_expr_op_or_else::ast_expr_op_or_else()
+    : ast_expr_op() {}
+
+ast_expr_op_or_else::ast_expr_op_or_else(const ast_expr_op_or_else &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_or_else::ast_expr_op_or_else(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_or_else &ast_expr_op_or_else::operator=(ast_expr_op_or_else obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_or_else::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_or_else &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_pdiv_q
+ast_expr_op_pdiv_q::ast_expr_op_pdiv_q()
+    : ast_expr_op() {}
+
+ast_expr_op_pdiv_q::ast_expr_op_pdiv_q(const ast_expr_op_pdiv_q &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_pdiv_q::ast_expr_op_pdiv_q(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_pdiv_q &ast_expr_op_pdiv_q::operator=(ast_expr_op_pdiv_q obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_pdiv_q::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_pdiv_q &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_pdiv_r
+ast_expr_op_pdiv_r::ast_expr_op_pdiv_r()
+    : ast_expr_op() {}
+
+ast_expr_op_pdiv_r::ast_expr_op_pdiv_r(const ast_expr_op_pdiv_r &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_pdiv_r::ast_expr_op_pdiv_r(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_pdiv_r &ast_expr_op_pdiv_r::operator=(ast_expr_op_pdiv_r obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_pdiv_r::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_pdiv_r &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_select
+ast_expr_op_select::ast_expr_op_select()
+    : ast_expr_op() {}
+
+ast_expr_op_select::ast_expr_op_select(const ast_expr_op_select &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_select::ast_expr_op_select(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_select &ast_expr_op_select::operator=(ast_expr_op_select obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_select::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_select &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_sub
+ast_expr_op_sub::ast_expr_op_sub()
+    : ast_expr_op() {}
+
+ast_expr_op_sub::ast_expr_op_sub(const ast_expr_op_sub &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_sub::ast_expr_op_sub(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_sub &ast_expr_op_sub::operator=(ast_expr_op_sub obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_sub::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_sub &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_expr_op_zdiv_r
+ast_expr_op_zdiv_r::ast_expr_op_zdiv_r()
+    : ast_expr_op() {}
+
+ast_expr_op_zdiv_r::ast_expr_op_zdiv_r(const ast_expr_op_zdiv_r &obj)
+    : ast_expr_op(obj)
+{
+}
+
+ast_expr_op_zdiv_r::ast_expr_op_zdiv_r(__isl_take isl_ast_expr *ptr)
+    : ast_expr_op(ptr) {}
+
+ast_expr_op_zdiv_r &ast_expr_op_zdiv_r::operator=(ast_expr_op_zdiv_r obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_expr_op_zdiv_r::ctx() const {
+  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_zdiv_r &obj)
+{
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
   auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  char *str = isl_ast_expr_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_node
+ast_node manage(__isl_take isl_ast_node *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return ast_node(ptr);
+}
+ast_node manage_copy(__isl_keep isl_ast_node *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_node_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_ast_node_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return ast_node(ptr);
+}
+
+ast_node::ast_node()
+    : ptr(nullptr) {}
+
+ast_node::ast_node(const ast_node &obj)
+    : ptr(nullptr)
+{
+  if (!obj.ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_node_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);
+}
+
+ast_node::ast_node(__isl_take isl_ast_node *ptr)
+    : ptr(ptr) {}
+
+ast_node &ast_node::operator=(ast_node obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+ast_node::~ast_node() {
+  if (ptr)
+    isl_ast_node_free(ptr);
+}
+
+__isl_give isl_ast_node *ast_node::copy() const & {
+  return isl_ast_node_copy(ptr);
+}
+
+__isl_keep isl_ast_node *ast_node::get() const {
+  return ptr;
+}
+
+__isl_give isl_ast_node *ast_node::release() {
+  isl_ast_node *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool ast_node::is_null() const {
+  return ptr == nullptr;
+}
+
+template <typename T, typename>
+bool ast_node::isa_type(T subtype) const
+{
+  if (is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl_ast_node_get_type(get()) == subtype;
+}
+template <class T>
+bool ast_node::isa() const
+{
+  return isa_type<decltype(T::type)>(T::type);
+}
+template <class T>
+T ast_node::as() const
+{
+ if (!isa<T>())
+    exception::throw_invalid("not an object of the requested subtype", __FILE__, __LINE__);
+  return T(copy());
+}
+
+isl::ctx ast_node::ctx() const {
+  return isl::ctx(isl_ast_node_get_ctx(ptr));
+}
+
+std::string ast_node::to_C_str() 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_C_str(get());
+  std::string tmp(res);
+  free(res);
+  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())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_node_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_node_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_node_block
+ast_node_block::ast_node_block()
+    : ast_node() {}
+
+ast_node_block::ast_node_block(const ast_node_block &obj)
+    : ast_node(obj)
+{
+}
+
+ast_node_block::ast_node_block(__isl_take isl_ast_node *ptr)
+    : ast_node(ptr) {}
+
+ast_node_block &ast_node_block::operator=(ast_node_block obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_node_block::ctx() const {
+  return isl::ctx(isl_ast_node_get_ctx(ptr));
+}
+
+isl::ast_node_list ast_node_block::children() 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_block_get_children(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_node_list ast_node_block::get_children() const
+{
+  return children();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_node_block &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_node_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_node_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_node_for
+ast_node_for::ast_node_for()
+    : ast_node() {}
+
+ast_node_for::ast_node_for(const ast_node_for &obj)
+    : ast_node(obj)
+{
+}
+
+ast_node_for::ast_node_for(__isl_take isl_ast_node *ptr)
+    : ast_node(ptr) {}
+
+ast_node_for &ast_node_for::operator=(ast_node_for obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_node_for::ctx() const {
+  return isl::ctx(isl_ast_node_get_ctx(ptr));
+}
+
+isl::ast_node ast_node_for::body() 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_get_body(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_node ast_node_for::get_body() const
+{
+  return body();
+}
+
+isl::ast_expr ast_node_for::cond() 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_get_cond(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_expr ast_node_for::get_cond() const
+{
+  return cond();
+}
+
+isl::ast_expr ast_node_for::inc() 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_get_inc(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_expr ast_node_for::get_inc() const
+{
+  return inc();
+}
+
+isl::ast_expr ast_node_for::init() 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_get_init(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_expr ast_node_for::get_init() const
+{
+  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)
+    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_get_iterator(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_expr ast_node_for::get_iterator() const
+{
+  return iterator();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_node_for &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_node_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_node_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_node_if
+ast_node_if::ast_node_if()
+    : ast_node() {}
+
+ast_node_if::ast_node_if(const ast_node_if &obj)
+    : ast_node(obj)
+{
+}
+
+ast_node_if::ast_node_if(__isl_take isl_ast_node *ptr)
+    : ast_node(ptr) {}
+
+ast_node_if &ast_node_if::operator=(ast_node_if obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_node_if::ctx() const {
+  return isl::ctx(isl_ast_node_get_ctx(ptr));
+}
+
+isl::ast_expr ast_node_if::cond() 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_get_cond(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_expr ast_node_if::get_cond() const
+{
+  return cond();
+}
+
+isl::ast_node ast_node_if::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_get_else_node(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_node ast_node_if::get_else_node() const
+{
+  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)
+    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_get_then_node(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_node ast_node_if::get_then_node() const
+{
+  return then_node();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_node_if &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_node_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_node_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_node_list
+ast_node_list manage(__isl_take isl_ast_node_list *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return ast_node_list(ptr);
+}
+ast_node_list manage_copy(__isl_keep isl_ast_node_list *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_node_list_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_ast_node_list_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return ast_node_list(ptr);
+}
+
+ast_node_list::ast_node_list()
+    : ptr(nullptr) {}
+
+ast_node_list::ast_node_list(const ast_node_list &obj)
+    : ptr(nullptr)
+{
+  if (!obj.ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_node_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);
+}
+
+ast_node_list::ast_node_list(__isl_take isl_ast_node_list *ptr)
+    : ptr(ptr) {}
+
+ast_node_list::ast_node_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_ast_node_list_alloc(ctx.release(), n);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+ast_node_list::ast_node_list(isl::ast_node 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_ast_node_list_from_ast_node(el.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+ast_node_list &ast_node_list::operator=(ast_node_list obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+ast_node_list::~ast_node_list() {
+  if (ptr)
+    isl_ast_node_list_free(ptr);
+}
+
+__isl_give isl_ast_node_list *ast_node_list::copy() const & {
+  return isl_ast_node_list_copy(ptr);
+}
+
+__isl_keep isl_ast_node_list *ast_node_list::get() const {
+  return ptr;
+}
+
+__isl_give isl_ast_node_list *ast_node_list::release() {
+  isl_ast_node_list *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool ast_node_list::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx ast_node_list::ctx() const {
+  return isl::ctx(isl_ast_node_list_get_ctx(ptr));
+}
+
+isl::ast_node_list ast_node_list::add(isl::ast_node 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_ast_node_list_add(copy(), el.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_clear(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_node_list ast_node_list::concat(isl::ast_node_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_ast_node_list_concat(copy(), list2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_node_list ast_node_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_ast_node_list_drop(copy(), first, n);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+void ast_node_list::foreach(const std::function<void(isl::ast_node)> &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::ast_node)> func;
+    std::exception_ptr eptr;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_ast_node *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_ast_node_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::ast_node_list ast_node_list::insert(unsigned int pos, isl::ast_node 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_ast_node_list_insert(copy(), pos, el.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+unsigned ast_node_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_ast_node_list_size(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_node_list &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_node_list_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_node_list_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_node_mark
+ast_node_mark::ast_node_mark()
+    : ast_node() {}
+
+ast_node_mark::ast_node_mark(const ast_node_mark &obj)
+    : ast_node(obj)
+{
+}
+
+ast_node_mark::ast_node_mark(__isl_take isl_ast_node *ptr)
+    : ast_node(ptr) {}
+
+ast_node_mark &ast_node_mark::operator=(ast_node_mark obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_node_mark::ctx() const {
+  return isl::ctx(isl_ast_node_get_ctx(ptr));
+}
+
+isl::id ast_node_mark::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_ast_node_mark_get_id(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id ast_node_mark::get_id() const
+{
+  return id();
+}
+
+isl::ast_node ast_node_mark::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_mark_get_node(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_node ast_node_mark::get_node() const
+{
+  return node();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_node_mark &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_node_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_node_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::ast_node_user
+ast_node_user::ast_node_user()
+    : ast_node() {}
+
+ast_node_user::ast_node_user(const ast_node_user &obj)
+    : ast_node(obj)
+{
+}
+
+ast_node_user::ast_node_user(__isl_take isl_ast_node *ptr)
+    : ast_node(ptr) {}
+
+ast_node_user &ast_node_user::operator=(ast_node_user obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx ast_node_user::ctx() const {
+  return isl::ctx(isl_ast_node_get_ctx(ptr));
+}
+
+isl::ast_expr ast_node_user::expr() 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_user_get_expr(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_expr ast_node_user::get_expr() const
+{
+  return expr();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const ast_node_user &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_ast_node_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_ast_node_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::basic_map
+basic_map manage(__isl_take isl_basic_map *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return basic_map(ptr);
+}
+basic_map manage_copy(__isl_keep isl_basic_map *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_basic_map_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_basic_map_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return basic_map(ptr);
+}
+
+basic_map::basic_map()
+    : ptr(nullptr) {}
+
+basic_map::basic_map(const basic_map &obj)
+    : ptr(nullptr)
+{
+  if (!obj.ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_basic_map_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);
+}
+
+basic_map::basic_map(__isl_take isl_basic_map *ptr)
+    : ptr(ptr) {}
+
+basic_map::basic_map(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_basic_map_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+basic_map &basic_map::operator=(basic_map obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+basic_map::~basic_map() {
+  if (ptr)
+    isl_basic_map_free(ptr);
+}
+
+__isl_give isl_basic_map *basic_map::copy() const & {
+  return isl_basic_map_copy(ptr);
+}
+
+__isl_keep isl_basic_map *basic_map::get() const {
+  return ptr;
+}
+
+__isl_give isl_basic_map *basic_map::release() {
+  isl_basic_map *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool basic_map::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx basic_map::ctx() const {
+  return isl::ctx(isl_basic_map_get_ctx(ptr));
+}
+
+isl::basic_map basic_map::affine_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_basic_map_affine_hull(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::basic_map basic_map::apply_domain(isl::basic_map bmap2) const
+{
+  if (!ptr || bmap2.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_basic_map_apply_domain(copy(), bmap2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_map_apply_range(copy(), bmap2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_map_deltas(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::basic_map basic_map::detect_equalities() 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_map_detect_equalities(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_map_flatten(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::basic_map basic_map::flatten_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_basic_map_flatten_domain(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::basic_map basic_map::flatten_range() 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_map_flatten_range(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_map_gist(copy(), context.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_map_intersect(copy(), bmap2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_map_intersect_domain(copy(), bset.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_map_intersect_range(copy(), bset.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_map_is_empty(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+bool basic_map::is_equal(const isl::basic_map &bmap2) const
+{
+  if (!ptr || bmap2.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_basic_map_is_equal(get(), bmap2.get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_map_is_subset(get(), bmap2.get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_map_lexmax(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_map_lexmin(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_map_reverse(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::basic_map basic_map::sample() 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_map_sample(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_map_union(copy(), bmap2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_basic_map_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_basic_map_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::basic_set
+basic_set manage(__isl_take isl_basic_set *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return basic_set(ptr);
+}
+basic_set manage_copy(__isl_keep isl_basic_set *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_basic_set_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_basic_set_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return basic_set(ptr);
+}
+
+basic_set::basic_set()
+    : ptr(nullptr) {}
+
+basic_set::basic_set(const basic_set &obj)
+    : ptr(nullptr)
+{
+  if (!obj.ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_basic_set_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);
+}
+
+basic_set::basic_set(__isl_take isl_basic_set *ptr)
+    : ptr(ptr) {}
+
+basic_set::basic_set(isl::point pnt)
+{
+  if (pnt.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = pnt.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_basic_set_from_point(pnt.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+basic_set::basic_set(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_basic_set_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+basic_set &basic_set::operator=(basic_set obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+basic_set::~basic_set() {
+  if (ptr)
+    isl_basic_set_free(ptr);
+}
+
+__isl_give isl_basic_set *basic_set::copy() const & {
+  return isl_basic_set_copy(ptr);
+}
+
+__isl_keep isl_basic_set *basic_set::get() const {
+  return ptr;
+}
+
+__isl_give isl_basic_set *basic_set::release() {
+  isl_basic_set *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool basic_set::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx basic_set::ctx() const {
+  return isl::ctx(isl_basic_set_get_ctx(ptr));
+}
+
+isl::basic_set basic_set::affine_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_basic_set_affine_hull(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::basic_set basic_set::apply(isl::basic_map bmap) const
+{
+  if (!ptr || bmap.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_basic_set_apply(copy(), bmap.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_detect_equalities(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::val basic_set::dim_max_val(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_basic_set_dim_max_val(copy(), pos);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_flatten(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_gist(copy(), context.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_intersect(copy(), bset2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_intersect_params(copy(), bset2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_is_empty(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+bool basic_set::is_equal(const isl::basic_set &bset2) const
+{
+  if (!ptr || bset2.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_basic_set_is_equal(get(), bset2.get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_is_subset(get(), bset2.get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_is_wrapping(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_lexmax(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_lexmin(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_params(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_sample(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::point basic_set::sample_point() 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_sample_point(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_union(copy(), bset2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_basic_set_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_basic_set_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::fixed_box
+fixed_box manage(__isl_take isl_fixed_box *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return fixed_box(ptr);
+}
+fixed_box manage_copy(__isl_keep isl_fixed_box *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_fixed_box_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_fixed_box_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return fixed_box(ptr);
+}
+
+fixed_box::fixed_box()
+    : ptr(nullptr) {}
+
+fixed_box::fixed_box(const fixed_box &obj)
+    : ptr(nullptr)
+{
+  if (!obj.ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_fixed_box_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);
+}
+
+fixed_box::fixed_box(__isl_take isl_fixed_box *ptr)
+    : ptr(ptr) {}
+
+fixed_box &fixed_box::operator=(fixed_box obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+fixed_box::~fixed_box() {
+  if (ptr)
+    isl_fixed_box_free(ptr);
+}
+
+__isl_give isl_fixed_box *fixed_box::copy() const & {
+  return isl_fixed_box_copy(ptr);
+}
+
+__isl_keep isl_fixed_box *fixed_box::get() const {
+  return ptr;
+}
+
+__isl_give isl_fixed_box *fixed_box::release() {
+  isl_fixed_box *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool fixed_box::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx fixed_box::ctx() const {
+  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)
+    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_get_offset(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff fixed_box::get_offset() const
+{
+  return offset();
+}
+
+isl::multi_val fixed_box::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_fixed_box_get_size(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_val fixed_box::get_size() const
+{
+  return size();
+}
+
+isl::space fixed_box::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_fixed_box_get_space(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space fixed_box::get_space() const
+{
+  return space();
+}
+
+inline std::ostream &operator<<(std::ostream &os, const fixed_box &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_fixed_box_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_fixed_box_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::id
+id manage(__isl_take isl_id *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return id(ptr);
+}
+id manage_copy(__isl_keep isl_id *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_id_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_id_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return id(ptr);
+}
+
+id::id()
+    : ptr(nullptr) {}
+
+id::id(const id &obj)
+    : ptr(nullptr)
+{
+  if (!obj.ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_id_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);
+}
+
+id::id(__isl_take isl_id *ptr)
+    : ptr(ptr) {}
+
+id::id(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_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+id &id::operator=(id obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+id::~id() {
+  if (ptr)
+    isl_id_free(ptr);
+}
+
+__isl_give isl_id *id::copy() const & {
+  return isl_id_copy(ptr);
+}
+
+__isl_keep isl_id *id::get() const {
+  return ptr;
+}
+
+__isl_give isl_id *id::release() {
+  isl_id *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool id::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx id::ctx() const {
+  return isl::ctx(isl_id_get_ctx(ptr));
+}
+
+std::string id::name() 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_get_name(get());
+  std::string tmp(res);
+  return tmp;
+}
+
+std::string id::get_name() const
+{
+  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())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_id_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_id_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::id_list
+id_list manage(__isl_take isl_id_list *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return id_list(ptr);
+}
+id_list manage_copy(__isl_keep isl_id_list *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_id_list_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_id_list_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return id_list(ptr);
+}
+
+id_list::id_list()
+    : ptr(nullptr) {}
+
+id_list::id_list(const id_list &obj)
+    : ptr(nullptr)
+{
+  if (!obj.ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_id_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);
+}
+
+id_list::id_list(__isl_take isl_id_list *ptr)
+    : ptr(ptr) {}
+
+id_list::id_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_id_list_alloc(ctx.release(), n);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+id_list::id_list(isl::id 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_id_list_from_id(el.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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;
+}
+
+id_list::~id_list() {
+  if (ptr)
+    isl_id_list_free(ptr);
+}
+
+__isl_give isl_id_list *id_list::copy() const & {
+  return isl_id_list_copy(ptr);
+}
+
+__isl_keep isl_id_list *id_list::get() const {
+  return ptr;
+}
+
+__isl_give isl_id_list *id_list::release() {
+  isl_id_list *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool id_list::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx id_list::ctx() const {
+  return isl::ctx(isl_id_list_get_ctx(ptr));
+}
+
+isl::id_list id_list::add(isl::id 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_id_list_add(copy(), el.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id_list id_list::add(const std::string &el) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  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)
+    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_clear(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id_list id_list::concat(isl::id_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_id_list_concat(copy(), list2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id_list id_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_id_list_drop(copy(), first, n);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+void id_list::foreach(const std::function<void(isl::id)> &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::id)> func;
+    std::exception_ptr eptr;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_id *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_id_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::id_list id_list::insert(unsigned int pos, isl::id 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_id_list_insert(copy(), pos, el.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id_list id_list::insert(unsigned int pos, const std::string &el) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->insert(pos, isl::id(ctx(), el));
+}
+
+unsigned id_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_id_list_size(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+inline std::ostream &operator<<(std::ostream &os, const id_list &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_id_list_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_id_list_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::map
+map manage(__isl_take isl_map *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return map(ptr);
+}
+map manage_copy(__isl_keep isl_map *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_map_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_map_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return map(ptr);
+}
+
+map::map()
+    : ptr(nullptr) {}
+
+map::map(const map &obj)
+    : ptr(nullptr)
+{
+  if (!obj.ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_map_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::map(__isl_take isl_map *ptr)
+    : ptr(ptr) {}
+
+map::map(isl::basic_map bmap)
+{
+  if (bmap.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = bmap.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_from_basic_map(bmap.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+map::map(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_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+map &map::operator=(map obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+map::~map() {
+  if (ptr)
+    isl_map_free(ptr);
+}
+
+__isl_give isl_map *map::copy() const & {
+  return isl_map_copy(ptr);
+}
+
+__isl_keep isl_map *map::get() const {
+  return ptr;
+}
+
+__isl_give isl_map *map::release() {
+  isl_map *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool map::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx map::ctx() const {
+  return isl::ctx(isl_map_get_ctx(ptr));
+}
+
+isl::basic_map map::affine_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_affine_hull(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::apply_domain(isl::map map2) const
+{
+  if (!ptr || map2.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_apply_domain(copy(), map2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_apply_range(copy(), map2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_bind_domain(copy(), tuple.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::set map::bind_range(isl::multi_id tuple) const
+{
+  if (!ptr || tuple.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_bind_range(copy(), tuple.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::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_map_coalesce(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::complement() 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_complement(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_curry(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::set map::deltas() 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_deltas(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::detect_equalities() 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_detect_equalities(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::set map::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_map_domain(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::domain_factor_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_map_domain_factor_domain(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::domain_factor_range() 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_factor_range(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_product(copy(), map2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_map_empty(space.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::eq_at(isl::multi_pw_aff mpa) const
+{
+  if (!ptr || mpa.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_eq_at_multi_pw_aff(copy(), mpa.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_factor_domain(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::factor_range() 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_factor_range(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_flatten(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::flatten_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_map_flatten_domain(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::flatten_range() 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_flatten_range(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+void map::foreach_basic_map(const std::function<void(isl::basic_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::basic_map)> func;
+    std::exception_ptr eptr;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_basic_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_foreach_basic_map(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;
+}
+
+void map::foreach_map(const std::function<void(isl::map)> &fn) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).foreach_map(fn);
+}
+
+isl::map map::gist(isl::map context) const
+{
+  if (!ptr || context.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_gist(copy(), context.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_gist_domain(copy(), context.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_intersect(copy(), map2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_intersect_domain(copy(), set.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_intersect_domain_factor_domain(copy(), factor.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_intersect_domain_factor_range(copy(), factor.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_intersect_params(copy(), params.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::intersect_range(isl::set set) const
+{
+  if (!ptr || set.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_intersect_range(copy(), set.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_intersect_range_factor_domain(copy(), factor.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_intersect_range_factor_range(copy(), factor.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_is_bijective(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+bool map::is_disjoint(const isl::map &map2) const
+{
+  if (!ptr || map2.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_is_disjoint(get(), map2.get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_is_empty(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+bool map::is_equal(const isl::map &map2) const
+{
+  if (!ptr || map2.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_is_equal(get(), map2.get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_is_injective(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+bool map::is_single_valued() 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_is_single_valued(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+bool map::is_strict_subset(const isl::map &map2) const
+{
+  if (!ptr || map2.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_is_strict_subset(get(), map2.get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_is_subset(get(), map2.get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_lex_ge_at_multi_pw_aff(copy(), mpa.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::lex_gt_at(isl::multi_pw_aff mpa) const
+{
+  if (!ptr || mpa.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_lex_gt_at_multi_pw_aff(copy(), mpa.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::lex_le_at(isl::multi_pw_aff mpa) const
+{
+  if (!ptr || mpa.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_lex_le_at_multi_pw_aff(copy(), mpa.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::lex_lt_at(isl::multi_pw_aff mpa) const
+{
+  if (!ptr || mpa.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_lex_lt_at_multi_pw_aff(copy(), mpa.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::lexmax() 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_lexmax(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_multi_aff map::lexmax_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_lexmax_pw_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::lexmin() 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_lexmin(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_multi_aff map::lexmin_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_lexmin_pw_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::lower_bound(isl::multi_pw_aff lower) const
+{
+  if (!ptr || lower.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_lower_bound_multi_pw_aff(copy(), lower.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_max_multi_pw_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_pw_aff map::min_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_map_min_multi_pw_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::basic_map map::polyhedral_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_polyhedral_hull(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::preimage_domain(isl::multi_aff ma) const
+{
+  if (!ptr || ma.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_preimage_domain_multi_aff(copy(), ma.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::preimage_domain(isl::multi_pw_aff mpa) const
+{
+  if (!ptr || mpa.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_preimage_domain_multi_pw_aff(copy(), mpa.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::preimage_domain(isl::pw_multi_aff pma) const
+{
+  if (!ptr || pma.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_preimage_domain_pw_multi_aff(copy(), pma.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_preimage_range_multi_aff(copy(), ma.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::preimage_range(isl::pw_multi_aff pma) const
+{
+  if (!ptr || pma.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_preimage_range_pw_multi_aff(copy(), pma.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_product(copy(), map2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_project_out_all_params(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::set map::range() 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(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::range_factor_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_map_range_factor_domain(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::range_factor_range() 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_factor_range(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_product(copy(), map2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_reverse(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_reverse(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::basic_map map::sample() 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_sample(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_subtract(copy(), map2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_uncurry(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::unite(isl::map map2) const
+{
+  if (!ptr || map2.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_union(copy(), map2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_map_universe(space.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::basic_map map::unshifted_simple_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_unshifted_simple_hull(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::upper_bound(isl::multi_pw_aff upper) const
+{
+  if (!ptr || upper.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_upper_bound_multi_pw_aff(copy(), upper.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::set map::wrap() 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_wrap(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::zip() 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_zip(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+inline std::ostream &operator<<(std::ostream &os, const map &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_map_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_map_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  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)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return multi_aff(ptr);
+}
+multi_aff manage_copy(__isl_keep isl_multi_aff *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_multi_aff_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_multi_aff_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return multi_aff(ptr);
+}
+
+multi_aff::multi_aff()
+    : ptr(nullptr) {}
+
+multi_aff::multi_aff(const multi_aff &obj)
+    : ptr(nullptr)
+{
+  if (!obj.ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_multi_aff_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);
+}
+
+multi_aff::multi_aff(__isl_take isl_multi_aff *ptr)
+    : ptr(ptr) {}
+
+multi_aff::multi_aff(isl::aff aff)
+{
+  if (aff.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = aff.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_from_aff(aff.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+multi_aff::multi_aff(isl::space space, isl::aff_list list)
+{
+  if (space.is_null() || list.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_from_aff_list(space.release(), list.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+multi_aff::multi_aff(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_multi_aff_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+multi_aff &multi_aff::operator=(multi_aff obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+multi_aff::~multi_aff() {
+  if (ptr)
+    isl_multi_aff_free(ptr);
+}
+
+__isl_give isl_multi_aff *multi_aff::copy() const & {
+  return isl_multi_aff_copy(ptr);
+}
+
+__isl_keep isl_multi_aff *multi_aff::get() const {
+  return ptr;
+}
+
+__isl_give isl_multi_aff *multi_aff::release() {
+  isl_multi_aff *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool multi_aff::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx multi_aff::ctx() const {
+  return isl::ctx(isl_multi_aff_get_ctx(ptr));
+}
+
+isl::multi_aff multi_aff::add(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_add(copy(), multi2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_add_constant_multi_val(copy(), mv.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff multi_aff::add_constant(isl::val v) const
+{
+  if (!ptr || v.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_add_constant_val(copy(), v.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff multi_aff::add_constant(long v) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  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())
+    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_bind(copy(), tuple.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff multi_aff::bind_domain(isl::multi_id tuple) const
+{
+  if (!ptr || tuple.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_bind_domain(copy(), tuple.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff multi_aff::bind_domain_wrapped_domain(isl::multi_id tuple) const
+{
+  if (!ptr || tuple.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_bind_domain_wrapped_domain(copy(), tuple.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_multi_aff multi_aff::coalesce() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).coalesce();
+}
+
+isl::multi_val multi_aff::constant_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_multi_aff_get_constant_multi_val(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_val multi_aff::get_constant_multi_val() const
+{
+  return constant_multi_val();
+}
+
+isl::set multi_aff::domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  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_domain_map(space.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+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_flat_range_product(copy(), multi2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_pw_aff multi_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 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
+{
+  if (!ptr || context.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_gist(copy(), context.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_identity_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff multi_aff::identity_on_domain(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_identity_on_domain_space(space.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff multi_aff::insert_domain(isl::space domain) const
+{
+  if (!ptr || domain.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_insert_domain(copy(), domain.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_involves_locals(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+bool multi_aff::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_aff_involves_nan(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_neg(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_plain_is_equal(get(), multi2.get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_product(copy(), multi2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_pullback_multi_aff(copy(), ma2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_range_map(space.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff multi_aff::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_range_product(copy(), multi2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_scale_multi_val(copy(), mv.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff multi_aff::scale(isl::val v) const
+{
+  if (!ptr || v.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_scale_val(copy(), v.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff multi_aff::scale(long v) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->scale(isl::val(ctx(), v));
+}
+
+isl::multi_aff multi_aff::scale_down(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_multi_aff_scale_down_multi_val(copy(), mv.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff multi_aff::scale_down(isl::val v) const
+{
+  if (!ptr || v.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_scale_down_val(copy(), v.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff multi_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_aff multi_aff::set_at(int pos, isl::aff 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_multi_aff_set_at(copy(), pos, el.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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)
+    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_size(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_sub(copy(), multi2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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())
+    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_unbind_params_insert_domain(copy(), domain.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::ast_expr_op_le
-ast_expr_op_le::ast_expr_op_le()
-    : ast_expr_op() {}
+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);
+}
 
-ast_expr_op_le::ast_expr_op_le(const ast_expr_op_le &obj)
-    : ast_expr_op(obj)
+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);
 }
 
-ast_expr_op_le::ast_expr_op_le(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+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);
+}
 
-ast_expr_op_le &ast_expr_op_le::operator=(ast_expr_op_le obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_op_le::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+isl::multi_aff multi_aff::zero(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_zero(space.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_le &obj)
+inline std::ostream &operator<<(std::ostream &os, const multi_aff &obj)
 {
   if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = isl_multi_aff_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
+  char *str = isl_multi_aff_to_str(obj.get());
   if (!str)
     exception::throw_last_error(saved_ctx);
   os << str;
@@ -4992,174 +13797,220 @@ inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_le &obj)
   return os;
 }
 
-// implementations for isl::ast_expr_op_lt
-ast_expr_op_lt::ast_expr_op_lt()
-    : ast_expr_op() {}
-
-ast_expr_op_lt::ast_expr_op_lt(const ast_expr_op_lt &obj)
-    : ast_expr_op(obj)
-{
+// implementations for isl::multi_id
+multi_id manage(__isl_take isl_multi_id *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return multi_id(ptr);
 }
-
-ast_expr_op_lt::ast_expr_op_lt(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_lt &ast_expr_op_lt::operator=(ast_expr_op_lt obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+multi_id manage_copy(__isl_keep isl_multi_id *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_multi_id_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_multi_id_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return multi_id(ptr);
 }
 
-isl::ctx ast_expr_op_lt::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
-}
+multi_id::multi_id()
+    : ptr(nullptr) {}
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_lt &obj)
+multi_id::multi_id(const multi_id &obj)
+    : ptr(nullptr)
 {
-  if (!obj.get())
+  if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = isl_multi_id_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  ptr = obj.copy();
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
 }
 
-// implementations for isl::ast_expr_op_max
-ast_expr_op_max::ast_expr_op_max()
-    : ast_expr_op() {}
+multi_id::multi_id(__isl_take isl_multi_id *ptr)
+    : ptr(ptr) {}
 
-ast_expr_op_max::ast_expr_op_max(const ast_expr_op_max &obj)
-    : ast_expr_op(obj)
+multi_id::multi_id(isl::space space, isl::id_list list)
 {
+  if (space.is_null() || list.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_id_from_id_list(space.release(), list.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
 }
 
-ast_expr_op_max::ast_expr_op_max(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+multi_id::multi_id(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_multi_id_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
 
-ast_expr_op_max &ast_expr_op_max::operator=(ast_expr_op_max obj) {
+multi_id &multi_id::operator=(multi_id obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-isl::ctx ast_expr_op_max::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+multi_id::~multi_id() {
+  if (ptr)
+    isl_multi_id_free(ptr);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_max &obj)
+__isl_give isl_multi_id *multi_id::copy() const & {
+  return isl_multi_id_copy(ptr);
+}
+
+__isl_keep isl_multi_id *multi_id::get() const {
+  return ptr;
+}
+
+__isl_give isl_multi_id *multi_id::release() {
+  isl_multi_id *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool multi_id::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx multi_id::ctx() const {
+  return isl::ctx(isl_multi_id_get_ctx(ptr));
+}
+
+isl::id multi_id::at(int pos) const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  auto res = isl_multi_id_get_at(get(), pos);
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::ast_expr_op_member
-ast_expr_op_member::ast_expr_op_member()
-    : ast_expr_op() {}
-
-ast_expr_op_member::ast_expr_op_member(const ast_expr_op_member &obj)
-    : ast_expr_op(obj)
+isl::id multi_id::get_at(int pos) const
 {
+  return at(pos);
 }
 
-ast_expr_op_member::ast_expr_op_member(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(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);
+}
 
-ast_expr_op_member &ast_expr_op_member::operator=(ast_expr_op_member obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::id_list multi_id::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_id_get_list(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::ctx ast_expr_op_member::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+isl::id_list multi_id::get_list() const
+{
+  return list();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_member &obj)
+bool multi_id::plain_is_equal(const isl::multi_id &multi2) const
 {
-  if (!obj.get())
+  if (!ptr || multi2.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  auto res = isl_multi_id_plain_is_equal(get(), multi2.get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return res;
 }
 
-// implementations for isl::ast_expr_op_min
-ast_expr_op_min::ast_expr_op_min()
-    : ast_expr_op() {}
-
-ast_expr_op_min::ast_expr_op_min(const ast_expr_op_min &obj)
-    : ast_expr_op(obj)
+isl::multi_id multi_id::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_range_product(copy(), multi2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-ast_expr_op_min::ast_expr_op_min(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_min &ast_expr_op_min::operator=(ast_expr_op_min obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::multi_id multi_id::set_at(int pos, isl::id 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_multi_id_set_at(copy(), pos, el.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::ctx ast_expr_op_min::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+isl::multi_id multi_id::set_at(int pos, const std::string &el) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_at(pos, isl::id(ctx(), el));
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_min &obj)
+unsigned multi_id::size() const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  auto res = isl_multi_id_size(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return res;
 }
 
-// implementations for isl::ast_expr_op_minus
-ast_expr_op_minus::ast_expr_op_minus()
-    : ast_expr_op() {}
-
-ast_expr_op_minus::ast_expr_op_minus(const ast_expr_op_minus &obj)
-    : ast_expr_op(obj)
+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);
 }
 
-ast_expr_op_minus::ast_expr_op_minus(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_minus &ast_expr_op_minus::operator=(ast_expr_op_minus obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx ast_expr_op_minus::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+isl::space multi_id::get_space() const
+{
+  return space();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_minus &obj)
+inline std::ostream &operator<<(std::ostream &os, const multi_id &obj)
 {
   if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = isl_multi_id_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
+  char *str = isl_multi_id_to_str(obj.get());
   if (!str)
     exception::throw_last_error(saved_ctx);
   os << str;
@@ -5167,1015 +14018,1071 @@ inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_minus &obj)
   return os;
 }
 
-// implementations for isl::ast_expr_op_mul
-ast_expr_op_mul::ast_expr_op_mul()
-    : ast_expr_op() {}
-
-ast_expr_op_mul::ast_expr_op_mul(const ast_expr_op_mul &obj)
-    : ast_expr_op(obj)
-{
+// implementations for isl::multi_pw_aff
+multi_pw_aff manage(__isl_take isl_multi_pw_aff *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return multi_pw_aff(ptr);
 }
-
-ast_expr_op_mul::ast_expr_op_mul(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_mul &ast_expr_op_mul::operator=(ast_expr_op_mul obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+multi_pw_aff manage_copy(__isl_keep isl_multi_pw_aff *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_multi_pw_aff_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_multi_pw_aff_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return multi_pw_aff(ptr);
 }
 
-isl::ctx ast_expr_op_mul::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
-}
+multi_pw_aff::multi_pw_aff()
+    : ptr(nullptr) {}
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_mul &obj)
+multi_pw_aff::multi_pw_aff(const multi_pw_aff &obj)
+    : ptr(nullptr)
 {
-  if (!obj.get())
+  if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = isl_multi_pw_aff_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  ptr = obj.copy();
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
 }
 
-// implementations for isl::ast_expr_op_or
-ast_expr_op_or::ast_expr_op_or()
-    : ast_expr_op() {}
+multi_pw_aff::multi_pw_aff(__isl_take isl_multi_pw_aff *ptr)
+    : ptr(ptr) {}
 
-ast_expr_op_or::ast_expr_op_or(const ast_expr_op_or &obj)
-    : ast_expr_op(obj)
+multi_pw_aff::multi_pw_aff(isl::aff aff)
 {
+  if (aff.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = aff.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_from_aff(aff.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
 }
 
-ast_expr_op_or::ast_expr_op_or(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_or &ast_expr_op_or::operator=(ast_expr_op_or obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx ast_expr_op_or::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
-}
-
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_or &obj)
+multi_pw_aff::multi_pw_aff(isl::multi_aff ma)
 {
-  if (!obj.get())
+  if (ma.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = ma.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  auto res = isl_multi_pw_aff_from_multi_aff(ma.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  ptr = res;
 }
 
-// implementations for isl::ast_expr_op_or_else
-ast_expr_op_or_else::ast_expr_op_or_else()
-    : ast_expr_op() {}
-
-ast_expr_op_or_else::ast_expr_op_or_else(const ast_expr_op_or_else &obj)
-    : ast_expr_op(obj)
+multi_pw_aff::multi_pw_aff(isl::pw_aff pa)
 {
+  if (pa.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = pa.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_from_pw_aff(pa.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
 }
 
-ast_expr_op_or_else::ast_expr_op_or_else(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_or_else &ast_expr_op_or_else::operator=(ast_expr_op_or_else obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx ast_expr_op_or_else::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+multi_pw_aff::multi_pw_aff(isl::space space, isl::pw_aff_list list)
+{
+  if (space.is_null() || list.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_pw_aff_from_pw_aff_list(space.release(), list.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_or_else &obj)
+multi_pw_aff::multi_pw_aff(isl::pw_multi_aff pma)
 {
-  if (!obj.get())
+  if (pma.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = pma.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  auto res = isl_multi_pw_aff_from_pw_multi_aff(pma.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  ptr = res;
 }
 
-// implementations for isl::ast_expr_op_pdiv_q
-ast_expr_op_pdiv_q::ast_expr_op_pdiv_q()
-    : ast_expr_op() {}
-
-ast_expr_op_pdiv_q::ast_expr_op_pdiv_q(const ast_expr_op_pdiv_q &obj)
-    : ast_expr_op(obj)
+multi_pw_aff::multi_pw_aff(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_multi_pw_aff_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
 }
 
-ast_expr_op_pdiv_q::ast_expr_op_pdiv_q(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_pdiv_q &ast_expr_op_pdiv_q::operator=(ast_expr_op_pdiv_q obj) {
+multi_pw_aff &multi_pw_aff::operator=(multi_pw_aff obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-isl::ctx ast_expr_op_pdiv_q::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+multi_pw_aff::~multi_pw_aff() {
+  if (ptr)
+    isl_multi_pw_aff_free(ptr);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_pdiv_q &obj)
-{
-  if (!obj.get())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+__isl_give isl_multi_pw_aff *multi_pw_aff::copy() const & {
+  return isl_multi_pw_aff_copy(ptr);
 }
 
-// implementations for isl::ast_expr_op_pdiv_r
-ast_expr_op_pdiv_r::ast_expr_op_pdiv_r()
-    : ast_expr_op() {}
-
-ast_expr_op_pdiv_r::ast_expr_op_pdiv_r(const ast_expr_op_pdiv_r &obj)
-    : ast_expr_op(obj)
-{
+__isl_keep isl_multi_pw_aff *multi_pw_aff::get() const {
+  return ptr;
 }
 
-ast_expr_op_pdiv_r::ast_expr_op_pdiv_r(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+__isl_give isl_multi_pw_aff *multi_pw_aff::release() {
+  isl_multi_pw_aff *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
 
-ast_expr_op_pdiv_r &ast_expr_op_pdiv_r::operator=(ast_expr_op_pdiv_r obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+bool multi_pw_aff::is_null() const {
+  return ptr == nullptr;
 }
 
-isl::ctx ast_expr_op_pdiv_r::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+isl::ctx multi_pw_aff::ctx() const {
+  return isl::ctx(isl_multi_pw_aff_get_ctx(ptr));
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_pdiv_r &obj)
+isl::multi_pw_aff multi_pw_aff::add(isl::multi_pw_aff multi2) const
 {
-  if (!obj.get())
+  if (!ptr || multi2.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  auto res = isl_multi_pw_aff_add(copy(), multi2.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::ast_expr_op_select
-ast_expr_op_select::ast_expr_op_select()
-    : ast_expr_op() {}
+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);
+}
 
-ast_expr_op_select::ast_expr_op_select(const ast_expr_op_select &obj)
-    : ast_expr_op(obj)
+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));
 }
 
-ast_expr_op_select::ast_expr_op_select(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+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));
+}
 
-ast_expr_op_select &ast_expr_op_select::operator=(ast_expr_op_select obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_expr_op_select::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+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));
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_select &obj)
+isl::multi_pw_aff multi_pw_aff::add_constant(isl::multi_val mv) const
 {
-  if (!obj.get())
+  if (!ptr || mv.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  auto res = isl_multi_pw_aff_add_constant_multi_val(copy(), mv.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::ast_expr_op_sub
-ast_expr_op_sub::ast_expr_op_sub()
-    : ast_expr_op() {}
-
-ast_expr_op_sub::ast_expr_op_sub(const ast_expr_op_sub &obj)
-    : ast_expr_op(obj)
+isl::multi_pw_aff multi_pw_aff::add_constant(isl::val v) const
 {
+  if (!ptr || v.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_add_constant_val(copy(), v.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-ast_expr_op_sub::ast_expr_op_sub(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
-
-ast_expr_op_sub &ast_expr_op_sub::operator=(ast_expr_op_sub obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::multi_pw_aff multi_pw_aff::add_constant(long v) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add_constant(isl::val(ctx(), v));
 }
 
-isl::ctx ast_expr_op_sub::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+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);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_sub &obj)
+isl::multi_aff multi_pw_aff::as_multi_aff() const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  auto res = isl_multi_pw_aff_as_multi_aff(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::ast_expr_op_zdiv_r
-ast_expr_op_zdiv_r::ast_expr_op_zdiv_r()
-    : ast_expr_op() {}
+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);
+}
 
-ast_expr_op_zdiv_r::ast_expr_op_zdiv_r(const ast_expr_op_zdiv_r &obj)
-    : ast_expr_op(obj)
+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);
 }
 
-ast_expr_op_zdiv_r::ast_expr_op_zdiv_r(__isl_take isl_ast_expr *ptr)
-    : ast_expr_op(ptr) {}
+isl::pw_aff multi_pw_aff::get_at(int pos) const
+{
+  return at(pos);
+}
 
-ast_expr_op_zdiv_r &ast_expr_op_zdiv_r::operator=(ast_expr_op_zdiv_r obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::set multi_pw_aff::bind(isl::multi_id tuple) const
+{
+  if (!ptr || tuple.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_bind(copy(), tuple.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::ctx ast_expr_op_zdiv_r::ctx() const {
-  return isl::ctx(isl_ast_expr_get_ctx(ptr));
+isl::multi_pw_aff multi_pw_aff::bind_domain(isl::multi_id tuple) const
+{
+  if (!ptr || tuple.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_bind_domain(copy(), tuple.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_zdiv_r &obj)
+isl::multi_pw_aff multi_pw_aff::bind_domain_wrapped_domain(isl::multi_id tuple) const
 {
-  if (!obj.get())
+  if (!ptr || tuple.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_expr_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_expr_to_str(obj.get());
-  if (!str)
+  auto res = isl_multi_pw_aff_bind_domain_wrapped_domain(copy(), tuple.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::ast_node
-ast_node manage(__isl_take isl_ast_node *ptr) {
+isl::multi_pw_aff multi_pw_aff::coalesce() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return ast_node(ptr);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_coalesce(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
-ast_node manage_copy(__isl_keep isl_ast_node *ptr) {
+
+isl::set multi_pw_aff::domain() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_node_get_ctx(ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_ast_node_copy(ptr);
-  if (!ptr)
+  auto res = isl_multi_pw_aff_domain(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return ast_node(ptr);
+  return manage(res);
 }
 
-ast_node::ast_node()
-    : ptr(nullptr) {}
-
-ast_node::ast_node(const ast_node &obj)
-    : ptr(nullptr)
+isl::multi_pw_aff multi_pw_aff::flat_range_product(isl::multi_pw_aff multi2) const
 {
-  if (!obj.ptr)
+  if (!ptr || multi2.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_node_get_ctx(obj.ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = obj.copy();
-  if (!ptr)
+  auto res = isl_multi_pw_aff_flat_range_product(copy(), multi2.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-ast_node::ast_node(__isl_take isl_ast_node *ptr)
-    : ptr(ptr) {}
-
-ast_node &ast_node::operator=(ast_node obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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__);
+  return isl::multi_union_pw_aff(*this).flat_range_product(multi2);
 }
 
-ast_node::~ast_node() {
-  if (ptr)
-    isl_ast_node_free(ptr);
+isl::multi_pw_aff multi_pw_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_pw_aff(multi2));
 }
 
-__isl_give isl_ast_node *ast_node::copy() const & {
-  return isl_ast_node_copy(ptr);
+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__);
+  return this->flat_range_product(isl::multi_pw_aff(multi2));
 }
 
-__isl_keep isl_ast_node *ast_node::get() const {
-  return ptr;
+isl::multi_pw_aff multi_pw_aff::flat_range_product(const isl::pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->flat_range_product(isl::multi_pw_aff(multi2));
 }
 
-__isl_give isl_ast_node *ast_node::release() {
-  isl_ast_node *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+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));
 }
 
-bool ast_node::is_null() const {
-  return ptr == nullptr;
+isl::multi_pw_aff multi_pw_aff::gist(isl::set set) const
+{
+  if (!ptr || set.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_gist(copy(), set.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-template <typename T, typename>
-bool ast_node::isa_type(T subtype) const
+isl::multi_union_pw_aff multi_pw_aff::gist(const isl::union_set &context) const
 {
-  if (is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return isl_ast_node_get_type(get()) == subtype;
+  return isl::multi_union_pw_aff(*this).gist(context);
 }
-template <class T>
-bool ast_node::isa() const
+
+isl::multi_pw_aff multi_pw_aff::gist(const isl::basic_set &set) const
 {
-  return isa_type<decltype(T::type)>(T::type);
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(set));
 }
-template <class T>
-T ast_node::as() const
+
+isl::multi_pw_aff multi_pw_aff::gist(const isl::point &set) const
 {
- if (!isa<T>())
-    exception::throw_invalid("not an object of the requested subtype", __FILE__, __LINE__);
-  return T(copy());
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(set));
 }
 
-isl::ctx ast_node::ctx() const {
-  return isl::ctx(isl_ast_node_get_ctx(ptr));
+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;
 }
 
-std::string ast_node::to_C_str() const
+isl::multi_pw_aff multi_pw_aff::identity() 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_C_str(get());
-  std::string tmp(res);
-  free(res);
-  return tmp;
+  auto res = isl_multi_pw_aff_identity_multi_pw_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_node &obj)
+isl::multi_pw_aff multi_pw_aff::identity_on_domain(isl::space space)
 {
-  if (!obj.get())
+  if (space.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_node_get_ctx(obj.get());
+  auto saved_ctx = space.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_node_to_str(obj.get());
-  if (!str)
+  auto res = isl_multi_pw_aff_identity_on_domain_space(space.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::ast_node_block
-ast_node_block::ast_node_block()
-    : ast_node() {}
-
-ast_node_block::ast_node_block(const ast_node_block &obj)
-    : ast_node(obj)
+isl::multi_pw_aff multi_pw_aff::insert_domain(isl::space domain) const
 {
+  if (!ptr || domain.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_insert_domain(copy(), domain.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-ast_node_block::ast_node_block(__isl_take isl_ast_node *ptr)
-    : ast_node(ptr) {}
+isl::multi_pw_aff multi_pw_aff::intersect_domain(isl::set domain) const
+{
+  if (!ptr || domain.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_intersect_domain(copy(), domain.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
 
-ast_node_block &ast_node_block::operator=(ast_node_block obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_node_block::ctx() const {
-  return isl::ctx(isl_ast_node_get_ctx(ptr));
+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::ast_node_list ast_node_block::children() const
+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())
+    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_block_get_children(get());
+  auto res = isl_multi_pw_aff_intersect_params(copy(), set.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_node_list ast_node_block::get_children() const
+bool multi_pw_aff::involves_nan() const
 {
-  return children();
+  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_involves_nan(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_node_block &obj)
+bool multi_pw_aff::involves_param(const isl::id &id) const
 {
-  if (!obj.get())
+  if (!ptr || id.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_node_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_node_to_str(obj.get());
-  if (!str)
+  auto res = isl_multi_pw_aff_involves_param_id(get(), id.get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return res;
 }
 
-// implementations for isl::ast_node_for
-ast_node_for::ast_node_for()
-    : ast_node() {}
-
-ast_node_for::ast_node_for(const ast_node_for &obj)
-    : ast_node(obj)
+bool multi_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));
 }
 
-ast_node_for::ast_node_for(__isl_take isl_ast_node *ptr)
-    : ast_node(ptr) {}
-
-ast_node_for &ast_node_for::operator=(ast_node_for obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+bool multi_pw_aff::involves_param(const 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_multi_pw_aff_involves_param_id_list(get(), list.get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
 }
 
-isl::ctx ast_node_for::ctx() const {
-  return isl::ctx(isl_ast_node_get_ctx(ptr));
+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::ast_node ast_node_for::body() const
+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_ast_node_for_get_body(get());
+  auto res = isl_multi_pw_aff_get_list(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_node ast_node_for::get_body() const
+isl::pw_aff_list multi_pw_aff::get_list() const
 {
-  return body();
+  return list();
 }
 
-isl::ast_expr ast_node_for::cond() const
+isl::multi_pw_aff multi_pw_aff::max(isl::multi_pw_aff multi2) const
 {
-  if (!ptr)
+  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_ast_node_for_get_cond(get());
+  auto res = isl_multi_pw_aff_max(copy(), multi2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_expr ast_node_for::get_cond() const
-{
-  return cond();
-}
-
-isl::ast_expr ast_node_for::inc() const
+isl::multi_val multi_pw_aff::max_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_ast_node_for_get_inc(get());
+  auto res = isl_multi_pw_aff_max_multi_val(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_expr ast_node_for::get_inc() const
+isl::multi_pw_aff multi_pw_aff::min(isl::multi_pw_aff multi2) const
 {
-  return inc();
+  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_pw_aff_min(copy(), multi2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::ast_expr ast_node_for::init() const
+isl::multi_val multi_pw_aff::min_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_ast_node_for_get_init(get());
+  auto res = isl_multi_pw_aff_min_multi_val(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_expr ast_node_for::get_init() const
-{
-  return init();
-}
-
-isl::ast_expr ast_node_for::iterator() const
+isl::multi_pw_aff multi_pw_aff::neg() 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_get_iterator(get());
+  auto res = isl_multi_pw_aff_neg(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_expr ast_node_for::get_iterator() const
-{
-  return iterator();
-}
-
-bool ast_node_for::is_degenerate() const
+bool multi_pw_aff::plain_is_equal(const isl::multi_pw_aff &multi2) const
 {
-  if (!ptr)
+  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_ast_node_for_is_degenerate(get());
+  auto res = isl_multi_pw_aff_plain_is_equal(get(), multi2.get());
   if (res < 0)
     exception::throw_last_error(saved_ctx);
   return res;
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_node_for &obj)
+bool multi_pw_aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_node_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_node_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return isl::multi_union_pw_aff(*this).plain_is_equal(multi2);
 }
 
-// implementations for isl::ast_node_if
-ast_node_if::ast_node_if()
-    : ast_node() {}
-
-ast_node_if::ast_node_if(const ast_node_if &obj)
-    : ast_node(obj)
+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));
 }
 
-ast_node_if::ast_node_if(__isl_take isl_ast_node *ptr)
-    : ast_node(ptr) {}
+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));
+}
 
-ast_node_if &ast_node_if::operator=(ast_node_if obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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));
 }
 
-isl::ctx ast_node_if::ctx() const {
-  return isl::ctx(isl_ast_node_get_ctx(ptr));
+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::ast_expr ast_node_if::cond() const
+isl::multi_pw_aff multi_pw_aff::product(isl::multi_pw_aff multi2) const
 {
-  if (!ptr)
+  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_ast_node_if_get_cond(get());
+  auto res = isl_multi_pw_aff_product(copy(), multi2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_expr ast_node_if::get_cond() const
-{
-  return cond();
-}
-
-isl::ast_node ast_node_if::else_node() const
+isl::multi_pw_aff multi_pw_aff::pullback(isl::multi_aff ma) const
 {
-  if (!ptr)
+  if (!ptr || ma.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_ast_node_if_get_else_node(get());
+  auto res = isl_multi_pw_aff_pullback_multi_aff(copy(), ma.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_node ast_node_if::get_else_node() const
+isl::multi_pw_aff multi_pw_aff::pullback(isl::multi_pw_aff mpa2) const
 {
-  return else_node();
+  if (!ptr || mpa2.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_pullback_multi_pw_aff(copy(), mpa2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::ast_node ast_node_if::then_node() const
+isl::multi_pw_aff multi_pw_aff::pullback(isl::pw_multi_aff pma) const
 {
-  if (!ptr)
+  if (!ptr || pma.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_ast_node_if_get_then_node(get());
+  auto res = isl_multi_pw_aff_pullback_pw_multi_aff(copy(), pma.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_node ast_node_if::get_then_node() const
+isl::multi_union_pw_aff multi_pw_aff::pullback(const isl::union_pw_multi_aff &upma) const
 {
-  return then_node();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).pullback(upma);
 }
 
-bool ast_node_if::has_else_node() const
+isl::multi_pw_aff multi_pw_aff::range_product(isl::multi_pw_aff multi2) const
 {
-  if (!ptr)
+  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_ast_node_if_has_else_node(get());
-  if (res < 0)
+  auto res = isl_multi_pw_aff_range_product(copy(), multi2.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_node_if &obj)
+isl::multi_union_pw_aff multi_pw_aff::range_product(const isl::multi_union_pw_aff &multi2) const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_node_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_node_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return isl::multi_union_pw_aff(*this).range_product(multi2);
 }
 
-// implementations for isl::ast_node_list
-ast_node_list manage(__isl_take isl_ast_node_list *ptr) {
+isl::multi_pw_aff multi_pw_aff::range_product(const isl::aff &multi2) const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return ast_node_list(ptr);
+  return this->range_product(isl::multi_pw_aff(multi2));
 }
-ast_node_list manage_copy(__isl_keep isl_ast_node_list *ptr) {
+
+isl::multi_pw_aff multi_pw_aff::range_product(const isl::multi_aff &multi2) const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_node_list_get_ctx(ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_ast_node_list_copy(ptr);
+  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_last_error(saved_ctx);
-  return ast_node_list(ptr);
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->range_product(isl::multi_pw_aff(multi2));
 }
 
-ast_node_list::ast_node_list()
-    : ptr(nullptr) {}
+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));
+}
 
-ast_node_list::ast_node_list(const ast_node_list &obj)
-    : ptr(nullptr)
+isl::id multi_pw_aff::range_tuple_id() const
 {
-  if (!obj.ptr)
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_node_list_get_ctx(obj.ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = obj.copy();
-  if (!ptr)
+  auto res = isl_multi_pw_aff_get_range_tuple_id(get());
+  if (!res)
     exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-ast_node_list::ast_node_list(__isl_take isl_ast_node_list *ptr)
-    : ptr(ptr) {}
+isl::id multi_pw_aff::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
 
-ast_node_list::ast_node_list(isl::ctx ctx, int n)
+isl::multi_pw_aff multi_pw_aff::reset_range_tuple_id() const
 {
-  auto saved_ctx = ctx;
+  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_alloc(ctx.release(), n);
+  auto res = isl_multi_pw_aff_reset_range_tuple_id(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-ast_node_list::ast_node_list(isl::ast_node el)
+isl::multi_pw_aff multi_pw_aff::scale(isl::multi_val mv) const
 {
-  if (el.is_null())
+  if (!ptr || mv.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = el.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_ast_node_list_from_ast_node(el.release());
+  auto res = isl_multi_pw_aff_scale_multi_val(copy(), mv.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-ast_node_list &ast_node_list::operator=(ast_node_list obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-ast_node_list::~ast_node_list() {
-  if (ptr)
-    isl_ast_node_list_free(ptr);
-}
-
-__isl_give isl_ast_node_list *ast_node_list::copy() const & {
-  return isl_ast_node_list_copy(ptr);
-}
-
-__isl_keep isl_ast_node_list *ast_node_list::get() const {
-  return ptr;
-}
-
-__isl_give isl_ast_node_list *ast_node_list::release() {
-  isl_ast_node_list *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+  return manage(res);
 }
 
-bool ast_node_list::is_null() const {
-  return ptr == nullptr;
+isl::multi_pw_aff multi_pw_aff::scale(isl::val v) const
+{
+  if (!ptr || v.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_scale_val(copy(), v.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::ctx ast_node_list::ctx() const {
-  return isl::ctx(isl_ast_node_list_get_ctx(ptr));
+isl::multi_pw_aff multi_pw_aff::scale(long v) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->scale(isl::val(ctx(), v));
 }
 
-isl::ast_node_list ast_node_list::add(isl::ast_node el) const
+isl::multi_pw_aff multi_pw_aff::scale_down(isl::multi_val mv) const
 {
-  if (!ptr || el.is_null())
+  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_ast_node_list_add(copy(), el.release());
+  auto res = isl_multi_pw_aff_scale_down_multi_val(copy(), mv.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_node_list ast_node_list::clear() const
+isl::multi_pw_aff multi_pw_aff::scale_down(isl::val v) const
 {
-  if (!ptr)
+  if (!ptr || v.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_ast_node_list_clear(copy());
+  auto res = isl_multi_pw_aff_scale_down_val(copy(), v.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_node_list ast_node_list::concat(isl::ast_node_list list2) const
+isl::multi_pw_aff multi_pw_aff::scale_down(long v) const
 {
-  if (!ptr || list2.is_null())
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->scale_down(isl::val(ctx(), v));
+}
+
+isl::multi_pw_aff multi_pw_aff::set_at(int pos, isl::pw_aff 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_ast_node_list_concat(copy(), list2.release());
+  auto res = isl_multi_pw_aff_set_at(copy(), pos, el.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_node_list ast_node_list::drop(unsigned int first, unsigned int n) const
+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_ast_node_list_drop(copy(), first, n);
+  auto res = isl_multi_pw_aff_set_range_tuple_id(copy(), id.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-void ast_node_list::foreach(const std::function<void(isl::ast_node)> &fn) const
+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)
     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::ast_node)> func;
-    std::exception_ptr eptr;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_ast_node *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_ast_node_list_foreach(get(), fn_lambda, &fn_data);
-  if (fn_data.eptr)
-    std::rethrow_exception(fn_data.eptr);
+  auto res = isl_multi_pw_aff_size(get());
   if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return;
+  return res;
 }
 
-isl::ast_node ast_node_list::at(int index) const
+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_ast_node_list_get_at(get(), index);
+  auto res = isl_multi_pw_aff_get_space(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_node ast_node_list::get_at(int index) const
+isl::space multi_pw_aff::get_space() const
 {
-  return at(index);
+  return space();
 }
 
-isl::ast_node_list ast_node_list::insert(unsigned int pos, isl::ast_node el) const
+isl::multi_pw_aff multi_pw_aff::sub(isl::multi_pw_aff multi2) const
 {
-  if (!ptr || el.is_null())
+  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_ast_node_list_insert(copy(), pos, el.release());
+  auto res = isl_multi_pw_aff_sub(copy(), multi2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-unsigned ast_node_list::size() const
+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__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_ast_node_list_size(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::multi_union_pw_aff(*this).sub(multi2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_node_list &obj)
+isl::multi_pw_aff multi_pw_aff::sub(const isl::aff &multi2) const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_node_list_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_node_list_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
-}
-
-// implementations for isl::ast_node_mark
-ast_node_mark::ast_node_mark()
-    : ast_node() {}
-
-ast_node_mark::ast_node_mark(const ast_node_mark &obj)
-    : ast_node(obj)
-{
+  return this->sub(isl::multi_pw_aff(multi2));
 }
 
-ast_node_mark::ast_node_mark(__isl_take isl_ast_node *ptr)
-    : ast_node(ptr) {}
-
-ast_node_mark &ast_node_mark::operator=(ast_node_mark obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_node_mark::ctx() const {
-  return isl::ctx(isl_ast_node_get_ctx(ptr));
+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::id ast_node_mark::id() const
+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())
+    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_mark_get_id(get());
+  auto res = isl_multi_pw_aff_unbind_params_insert_domain(copy(), domain.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::id ast_node_mark::get_id() const
-{
-  return id();
-}
-
-isl::ast_node ast_node_mark::node() const
+isl::multi_pw_aff multi_pw_aff::union_add(isl::multi_pw_aff mpa2) const
 {
-  if (!ptr)
+  if (!ptr || mpa2.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_ast_node_mark_get_node(get());
+  auto res = isl_multi_pw_aff_union_add(copy(), mpa2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_node ast_node_mark::get_node() const
+isl::multi_union_pw_aff multi_pw_aff::union_add(const isl::multi_union_pw_aff &mupa2) const
 {
-  return node();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).union_add(mupa2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const ast_node_mark &obj)
+isl::multi_pw_aff multi_pw_aff::union_add(const isl::aff &mpa2) const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_node_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_node_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return this->union_add(isl::multi_pw_aff(mpa2));
 }
 
-// implementations for isl::ast_node_user
-ast_node_user::ast_node_user()
-    : ast_node() {}
-
-ast_node_user::ast_node_user(const ast_node_user &obj)
-    : ast_node(obj)
+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));
 }
 
-ast_node_user::ast_node_user(__isl_take isl_ast_node *ptr)
-    : ast_node(ptr) {}
-
-ast_node_user &ast_node_user::operator=(ast_node_user obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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::ctx ast_node_user::ctx() const {
-  return isl::ctx(isl_ast_node_get_ctx(ptr));
+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::ast_expr ast_node_user::expr() const
+isl::multi_pw_aff multi_pw_aff::zero(isl::space space)
 {
-  if (!ptr)
+  if (space.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = space.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_ast_node_user_get_expr(get());
+  auto res = isl_multi_pw_aff_zero(space.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::ast_expr ast_node_user::get_expr() const
-{
-  return expr();
-}
-
-inline std::ostream &operator<<(std::ostream &os, const ast_node_user &obj)
+inline std::ostream &operator<<(std::ostream &os, const multi_pw_aff &obj)
 {
   if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_ast_node_get_ctx(obj.get());
+  auto saved_ctx = isl_multi_pw_aff_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_ast_node_to_str(obj.get());
+  char *str = isl_multi_pw_aff_to_str(obj.get());
   if (!str)
     exception::throw_last_error(saved_ctx);
   os << str;
@@ -6183,649 +15090,515 @@ inline std::ostream &operator<<(std::ostream &os, const ast_node_user &obj)
   return os;
 }
 
-// implementations for isl::basic_map
-basic_map manage(__isl_take isl_basic_map *ptr) {
+// implementations for isl::multi_union_pw_aff
+multi_union_pw_aff manage(__isl_take isl_multi_union_pw_aff *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return basic_map(ptr);
+  return multi_union_pw_aff(ptr);
 }
-basic_map manage_copy(__isl_keep isl_basic_map *ptr) {
+multi_union_pw_aff manage_copy(__isl_keep isl_multi_union_pw_aff *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_basic_map_get_ctx(ptr);
+  auto saved_ctx = isl_multi_union_pw_aff_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_basic_map_copy(ptr);
+  ptr = isl_multi_union_pw_aff_copy(ptr);
   if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return basic_map(ptr);
+  return multi_union_pw_aff(ptr);
 }
 
-basic_map::basic_map()
+multi_union_pw_aff::multi_union_pw_aff()
     : ptr(nullptr) {}
 
-basic_map::basic_map(const basic_map &obj)
+multi_union_pw_aff::multi_union_pw_aff(const multi_union_pw_aff &obj)
     : ptr(nullptr)
 {
   if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_basic_map_get_ctx(obj.ptr);
+  auto saved_ctx = isl_multi_union_pw_aff_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);
 }
 
-basic_map::basic_map(__isl_take isl_basic_map *ptr)
+multi_union_pw_aff::multi_union_pw_aff(__isl_take isl_multi_union_pw_aff *ptr)
     : ptr(ptr) {}
 
-basic_map::basic_map(isl::ctx ctx, const std::string &str)
+multi_union_pw_aff::multi_union_pw_aff(isl::multi_pw_aff mpa)
 {
-  auto saved_ctx = ctx;
+  if (mpa.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = mpa.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_basic_map_read_from_str(ctx.release(), str.c_str());
+  auto res = isl_multi_union_pw_aff_from_multi_pw_aff(mpa.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   ptr = res;
 }
 
-basic_map &basic_map::operator=(basic_map obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-basic_map::~basic_map() {
-  if (ptr)
-    isl_basic_map_free(ptr);
-}
-
-__isl_give isl_basic_map *basic_map::copy() const & {
-  return isl_basic_map_copy(ptr);
-}
-
-__isl_keep isl_basic_map *basic_map::get() const {
-  return ptr;
-}
-
-__isl_give isl_basic_map *basic_map::release() {
-  isl_basic_map *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
-}
-
-bool basic_map::is_null() const {
-  return ptr == nullptr;
-}
-
-isl::ctx basic_map::ctx() const {
-  return isl::ctx(isl_basic_map_get_ctx(ptr));
-}
-
-isl::basic_map basic_map::affine_hull() const
+multi_union_pw_aff::multi_union_pw_aff(isl::union_pw_aff upa)
 {
-  if (!ptr)
+  if (upa.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = upa.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_basic_map_affine_hull(copy());
+  auto res = isl_multi_union_pw_aff_from_union_pw_aff(upa.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  ptr = res;
 }
 
-isl::basic_map basic_map::apply_domain(isl::basic_map bmap2) const
+multi_union_pw_aff::multi_union_pw_aff(isl::space space, isl::union_pw_aff_list list)
 {
-  if (!ptr || bmap2.is_null())
+  if (space.is_null() || list.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = space.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_basic_map_apply_domain(copy(), bmap2.release());
+  auto res = isl_multi_union_pw_aff_from_union_pw_aff_list(space.release(), list.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  ptr = res;
 }
 
-isl::basic_map basic_map::apply_range(isl::basic_map bmap2) const
+multi_union_pw_aff::multi_union_pw_aff(isl::ctx ctx, const std::string &str)
 {
-  if (!ptr || bmap2.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = ctx;
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_basic_map_apply_range(copy(), bmap2.release());
+  auto res = isl_multi_union_pw_aff_read_from_str(ctx.release(), str.c_str());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  ptr = res;
 }
 
-isl::basic_set basic_map::deltas() 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_map_deltas(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+multi_union_pw_aff &multi_union_pw_aff::operator=(multi_union_pw_aff obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
 }
 
-isl::basic_map basic_map::detect_equalities() 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_map_detect_equalities(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+multi_union_pw_aff::~multi_union_pw_aff() {
+  if (ptr)
+    isl_multi_union_pw_aff_free(ptr);
 }
 
-isl::basic_map basic_map::flatten() 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_map_flatten(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+__isl_give isl_multi_union_pw_aff *multi_union_pw_aff::copy() const & {
+  return isl_multi_union_pw_aff_copy(ptr);
 }
 
-isl::basic_map basic_map::flatten_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_basic_map_flatten_domain(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+__isl_keep isl_multi_union_pw_aff *multi_union_pw_aff::get() const {
+  return ptr;
 }
 
-isl::basic_map basic_map::flatten_range() 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_map_flatten_range(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+__isl_give isl_multi_union_pw_aff *multi_union_pw_aff::release() {
+  isl_multi_union_pw_aff *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
 }
 
-isl::basic_map basic_map::gist(isl::basic_map context) const
+bool multi_union_pw_aff::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx multi_union_pw_aff::ctx() const {
+  return isl::ctx(isl_multi_union_pw_aff_get_ctx(ptr));
+}
+
+isl::multi_union_pw_aff multi_union_pw_aff::add(isl::multi_union_pw_aff multi2) const
 {
-  if (!ptr || context.is_null())
+  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_basic_map_gist(copy(), context.release());
+  auto res = isl_multi_union_pw_aff_add(copy(), multi2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::basic_map basic_map::intersect(isl::basic_map bmap2) const
+isl::union_pw_aff multi_union_pw_aff::at(int pos) const
 {
-  if (!ptr || bmap2.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_basic_map_intersect(copy(), bmap2.release());
+  auto res = isl_multi_union_pw_aff_get_at(get(), pos);
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::basic_map basic_map::intersect_domain(isl::basic_set bset) const
+isl::union_pw_aff multi_union_pw_aff::get_at(int pos) const
 {
-  if (!ptr || bset.is_null())
+  return at(pos);
+}
+
+isl::union_set multi_union_pw_aff::bind(isl::multi_id tuple) const
+{
+  if (!ptr || tuple.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_basic_map_intersect_domain(copy(), bset.release());
+  auto res = isl_multi_union_pw_aff_bind(copy(), tuple.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::basic_map basic_map::intersect_range(isl::basic_set bset) const
+isl::multi_union_pw_aff multi_union_pw_aff::coalesce() const
 {
-  if (!ptr || bset.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_basic_map_intersect_range(copy(), bset.release());
+  auto res = isl_multi_union_pw_aff_coalesce(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool basic_map::is_empty() const
+isl::union_set multi_union_pw_aff::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_basic_map_is_empty(get());
-  if (res < 0)
+  auto res = isl_multi_union_pw_aff_domain(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-bool basic_map::is_equal(const isl::basic_map &bmap2) const
+isl::multi_union_pw_aff multi_union_pw_aff::flat_range_product(isl::multi_union_pw_aff multi2) const
 {
-  if (!ptr || bmap2.is_null())
+  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_basic_map_is_equal(get(), bmap2.get());
-  if (res < 0)
+  auto res = isl_multi_union_pw_aff_flat_range_product(copy(), multi2.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-bool basic_map::is_subset(const isl::basic_map &bmap2) const
+isl::multi_union_pw_aff multi_union_pw_aff::gist(isl::union_set context) const
 {
-  if (!ptr || bmap2.is_null())
+  if (!ptr || context.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_basic_map_is_subset(get(), bmap2.get());
-  if (res < 0)
+  auto res = isl_multi_union_pw_aff_gist(copy(), context.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-isl::map basic_map::lexmax() const
+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_basic_map_lexmax(copy());
-  if (!res)
+  auto res = isl_multi_union_pw_aff_has_range_tuple_id(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::map basic_map::lexmin() const
+isl::multi_union_pw_aff multi_union_pw_aff::intersect_domain(isl::union_set uset) const
 {
-  if (!ptr)
+  if (!ptr || uset.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_basic_map_lexmin(copy());
+  auto res = isl_multi_union_pw_aff_intersect_domain(copy(), uset.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::basic_map basic_map::reverse() const
+isl::multi_union_pw_aff multi_union_pw_aff::intersect_params(isl::set params) const
 {
-  if (!ptr)
+  if (!ptr || params.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_basic_map_reverse(copy());
+  auto res = isl_multi_union_pw_aff_intersect_params(copy(), params.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::basic_map basic_map::sample() const
+bool multi_union_pw_aff::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_basic_map_sample(copy());
-  if (!res)
+  auto res = isl_multi_union_pw_aff_involves_nan(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::map basic_map::unite(isl::basic_map bmap2) const
+isl::union_pw_aff_list multi_union_pw_aff::list() const
 {
-  if (!ptr || bmap2.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_basic_map_union(copy(), bmap2.release());
+  auto res = isl_multi_union_pw_aff_get_list(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const basic_map &obj)
+isl::union_pw_aff_list multi_union_pw_aff::get_list() const
 {
-  if (!obj.get())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_basic_map_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_basic_map_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
-}
-
-// implementations for isl::basic_set
-basic_set manage(__isl_take isl_basic_set *ptr) {
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return basic_set(ptr);
-}
-basic_set manage_copy(__isl_keep isl_basic_set *ptr) {
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_basic_set_get_ctx(ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_basic_set_copy(ptr);
-  if (!ptr)
-    exception::throw_last_error(saved_ctx);
-  return basic_set(ptr);
+  return list();
 }
 
-basic_set::basic_set()
-    : ptr(nullptr) {}
-
-basic_set::basic_set(const basic_set &obj)
-    : ptr(nullptr)
+isl::multi_union_pw_aff multi_union_pw_aff::neg() const
 {
-  if (!obj.ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_basic_set_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);
-}
-
-basic_set::basic_set(__isl_take isl_basic_set *ptr)
-    : ptr(ptr) {}
-
-basic_set::basic_set(isl::point pnt)
-{
-  if (pnt.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = pnt.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_basic_set_from_point(pnt.release());
+  auto res = isl_multi_union_pw_aff_neg(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-basic_set::basic_set(isl::ctx ctx, const std::string &str)
+bool multi_union_pw_aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const
 {
-  auto saved_ctx = ctx;
+  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_basic_set_read_from_str(ctx.release(), str.c_str());
-  if (!res)
+  auto res = isl_multi_union_pw_aff_plain_is_equal(get(), multi2.get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-basic_set &basic_set::operator=(basic_set obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-basic_set::~basic_set() {
-  if (ptr)
-    isl_basic_set_free(ptr);
-}
-
-__isl_give isl_basic_set *basic_set::copy() const & {
-  return isl_basic_set_copy(ptr);
-}
-
-__isl_keep isl_basic_set *basic_set::get() const {
-  return ptr;
-}
-
-__isl_give isl_basic_set *basic_set::release() {
-  isl_basic_set *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
-}
-
-bool basic_set::is_null() const {
-  return ptr == nullptr;
-}
-
-isl::ctx basic_set::ctx() const {
-  return isl::ctx(isl_basic_set_get_ctx(ptr));
+  return res;
 }
 
-isl::basic_set basic_set::affine_hull() const
+isl::multi_union_pw_aff multi_union_pw_aff::pullback(isl::union_pw_multi_aff upma) const
 {
-  if (!ptr)
+  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_basic_set_affine_hull(copy());
+  auto res = isl_multi_union_pw_aff_pullback_union_pw_multi_aff(copy(), upma.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::basic_set basic_set::apply(isl::basic_map bmap) const
+isl::multi_union_pw_aff multi_union_pw_aff::range_product(isl::multi_union_pw_aff multi2) const
 {
-  if (!ptr || bmap.is_null())
+  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_basic_set_apply(copy(), bmap.release());
+  auto res = isl_multi_union_pw_aff_range_product(copy(), multi2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::basic_set basic_set::detect_equalities() const
+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_basic_set_detect_equalities(copy());
+  auto res = isl_multi_union_pw_aff_get_range_tuple_id(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::val basic_set::dim_max_val(int pos) const
+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_basic_set_dim_max_val(copy(), pos);
+  auto res = isl_multi_union_pw_aff_reset_range_tuple_id(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::basic_set basic_set::flatten() const
+isl::multi_union_pw_aff multi_union_pw_aff::scale(isl::multi_val mv) const
 {
-  if (!ptr)
+  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_basic_set_flatten(copy());
+  auto res = isl_multi_union_pw_aff_scale_multi_val(copy(), mv.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::basic_set basic_set::gist(isl::basic_set context) const
+isl::multi_union_pw_aff multi_union_pw_aff::scale(isl::val v) const
 {
-  if (!ptr || context.is_null())
+  if (!ptr || v.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_basic_set_gist(copy(), context.release());
+  auto res = isl_multi_union_pw_aff_scale_val(copy(), v.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::basic_set basic_set::intersect(isl::basic_set bset2) const
+isl::multi_union_pw_aff multi_union_pw_aff::scale(long v) const
 {
-  if (!ptr || bset2.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_basic_set_intersect(copy(), bset2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->scale(isl::val(ctx(), v));
 }
 
-isl::basic_set basic_set::intersect_params(isl::basic_set bset2) const
+isl::multi_union_pw_aff multi_union_pw_aff::scale_down(isl::multi_val mv) const
 {
-  if (!ptr || bset2.is_null())
+  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_basic_set_intersect_params(copy(), bset2.release());
+  auto res = isl_multi_union_pw_aff_scale_down_multi_val(copy(), mv.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool basic_set::is_empty() const
+isl::multi_union_pw_aff multi_union_pw_aff::scale_down(isl::val v) const
 {
-  if (!ptr)
+  if (!ptr || v.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_basic_set_is_empty(get());
-  if (res < 0)
+  auto res = isl_multi_union_pw_aff_scale_down_val(copy(), v.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-bool basic_set::is_equal(const isl::basic_set &bset2) const
+isl::multi_union_pw_aff multi_union_pw_aff::scale_down(long v) const
 {
-  if (!ptr || bset2.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_basic_set_is_equal(get(), bset2.get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return this->scale_down(isl::val(ctx(), v));
 }
 
-bool basic_set::is_subset(const isl::basic_set &bset2) const
+isl::multi_union_pw_aff multi_union_pw_aff::set_at(int pos, isl::union_pw_aff el) const
 {
-  if (!ptr || bset2.is_null())
+  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_basic_set_is_subset(get(), bset2.get());
-  if (res < 0)
+  auto res = isl_multi_union_pw_aff_set_at(copy(), pos, el.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-bool basic_set::is_wrapping() const
+isl::multi_union_pw_aff multi_union_pw_aff::set_range_tuple(isl::id id) const
 {
-  if (!ptr)
+  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_basic_set_is_wrapping(get());
-  if (res < 0)
+  auto res = isl_multi_union_pw_aff_set_range_tuple_id(copy(), id.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-isl::set basic_set::lexmax() const
+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__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_basic_set_lexmax(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->set_range_tuple(isl::id(ctx(), id));
 }
 
-isl::set basic_set::lexmin() const
+unsigned multi_union_pw_aff::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_basic_set_lexmin(copy());
-  if (!res)
+  auto res = isl_multi_union_pw_aff_size(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::basic_set basic_set::params() const
+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_basic_set_params(copy());
+  auto res = isl_multi_union_pw_aff_get_space(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::basic_set basic_set::sample() const
+isl::space multi_union_pw_aff::get_space() const
 {
-  if (!ptr)
+  return space();
+}
+
+isl::multi_union_pw_aff multi_union_pw_aff::sub(isl::multi_union_pw_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_basic_set_sample(copy());
+  auto res = isl_multi_union_pw_aff_sub(copy(), multi2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::point basic_set::sample_point() const
+isl::multi_union_pw_aff multi_union_pw_aff::union_add(isl::multi_union_pw_aff mupa2) const
 {
-  if (!ptr)
+  if (!ptr || mupa2.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_basic_set_sample_point(copy());
+  auto res = isl_multi_union_pw_aff_union_add(copy(), mupa2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set basic_set::unite(isl::basic_set bset2) const
+isl::multi_union_pw_aff multi_union_pw_aff::zero(isl::space space)
 {
-  if (!ptr || bset2.is_null())
+  if (space.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = space.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_basic_set_union(copy(), bset2.release());
+  auto res = isl_multi_union_pw_aff_zero(space.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const basic_set &obj)
+inline std::ostream &operator<<(std::ostream &os, const multi_union_pw_aff &obj)
 {
   if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_basic_set_get_ctx(obj.get());
+  auto saved_ctx = isl_multi_union_pw_aff_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_basic_set_to_str(obj.get());
+  char *str = isl_multi_union_pw_aff_to_str(obj.get());
   if (!str)
     exception::throw_last_error(saved_ctx);
   os << str;
@@ -6833,484 +15606,457 @@ inline std::ostream &operator<<(std::ostream &os, const basic_set &obj)
   return os;
 }
 
-// implementations for isl::fixed_box
-fixed_box manage(__isl_take isl_fixed_box *ptr) {
+// implementations for isl::multi_val
+multi_val manage(__isl_take isl_multi_val *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return fixed_box(ptr);
+  return multi_val(ptr);
 }
-fixed_box manage_copy(__isl_keep isl_fixed_box *ptr) {
+multi_val manage_copy(__isl_keep isl_multi_val *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_fixed_box_get_ctx(ptr);
+  auto saved_ctx = isl_multi_val_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_fixed_box_copy(ptr);
+  ptr = isl_multi_val_copy(ptr);
   if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return fixed_box(ptr);
+  return multi_val(ptr);
 }
 
-fixed_box::fixed_box()
+multi_val::multi_val()
     : ptr(nullptr) {}
 
-fixed_box::fixed_box(const fixed_box &obj)
+multi_val::multi_val(const multi_val &obj)
     : ptr(nullptr)
 {
   if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_fixed_box_get_ctx(obj.ptr);
+  auto saved_ctx = isl_multi_val_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);
 }
 
-fixed_box::fixed_box(__isl_take isl_fixed_box *ptr)
+multi_val::multi_val(__isl_take isl_multi_val *ptr)
     : ptr(ptr) {}
 
-fixed_box &fixed_box::operator=(fixed_box obj) {
+multi_val::multi_val(isl::space space, isl::val_list list)
+{
+  if (space.is_null() || list.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_val_from_val_list(space.release(), list.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+multi_val::multi_val(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_multi_val_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+multi_val &multi_val::operator=(multi_val obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-fixed_box::~fixed_box() {
+multi_val::~multi_val() {
   if (ptr)
-    isl_fixed_box_free(ptr);
+    isl_multi_val_free(ptr);
 }
 
-__isl_give isl_fixed_box *fixed_box::copy() const & {
-  return isl_fixed_box_copy(ptr);
+__isl_give isl_multi_val *multi_val::copy() const & {
+  return isl_multi_val_copy(ptr);
 }
 
-__isl_keep isl_fixed_box *fixed_box::get() const {
+__isl_keep isl_multi_val *multi_val::get() const {
   return ptr;
 }
 
-__isl_give isl_fixed_box *fixed_box::release() {
-  isl_fixed_box *tmp = ptr;
+__isl_give isl_multi_val *multi_val::release() {
+  isl_multi_val *tmp = ptr;
   ptr = nullptr;
   return tmp;
 }
 
-bool fixed_box::is_null() const {
+bool multi_val::is_null() const {
   return ptr == nullptr;
 }
 
-isl::ctx fixed_box::ctx() const {
-  return isl::ctx(isl_fixed_box_get_ctx(ptr));
+isl::ctx multi_val::ctx() const {
+  return isl::ctx(isl_multi_val_get_ctx(ptr));
 }
 
-isl::multi_aff fixed_box::offset() const
+isl::multi_val multi_val::add(isl::multi_val multi2) const
 {
-  if (!ptr)
+  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_fixed_box_get_offset(get());
+  auto res = isl_multi_val_add(copy(), multi2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_aff fixed_box::get_offset() const
-{
-  return offset();
-}
-
-isl::multi_val fixed_box::size() const
+isl::multi_val multi_val::add(isl::val v) const
 {
-  if (!ptr)
+  if (!ptr || v.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_fixed_box_get_size(get());
+  auto res = isl_multi_val_add_val(copy(), v.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_val fixed_box::get_size() const
+isl::multi_val multi_val::add(long v) const
 {
-  return size();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add(isl::val(ctx(), v));
 }
 
-isl::space fixed_box::space() const
+isl::val multi_val::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_fixed_box_get_space(get());
+  auto res = isl_multi_val_get_at(get(), pos);
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space fixed_box::get_space() const
+isl::val multi_val::get_at(int pos) const
 {
-  return space();
+  return at(pos);
 }
 
-bool fixed_box::is_valid() const
+isl::multi_val multi_val::flat_range_product(isl::multi_val multi2) const
 {
-  if (!ptr)
+  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_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())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_fixed_box_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_fixed_box_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
-}
-
-// implementations for isl::id
-id manage(__isl_take isl_id *ptr) {
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return id(ptr);
-}
-id manage_copy(__isl_keep isl_id *ptr) {
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_id_get_ctx(ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_id_copy(ptr);
-  if (!ptr)
-    exception::throw_last_error(saved_ctx);
-  return id(ptr);
-}
-
-id::id()
-    : ptr(nullptr) {}
-
-id::id(const id &obj)
-    : ptr(nullptr)
-{
-  if (!obj.ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_id_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);
-}
-
-id::id(__isl_take isl_id *ptr)
-    : ptr(ptr) {}
-
-id::id(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_read_from_str(ctx.release(), str.c_str());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-id &id::operator=(id obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-id::~id() {
-  if (ptr)
-    isl_id_free(ptr);
-}
-
-__isl_give isl_id *id::copy() const & {
-  return isl_id_copy(ptr);
-}
-
-__isl_keep isl_id *id::get() const {
-  return ptr;
-}
-
-__isl_give isl_id *id::release() {
-  isl_id *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+  auto res = isl_multi_val_flat_range_product(copy(), multi2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-bool id::is_null() const {
-  return ptr == nullptr;
+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;
 }
 
-isl::ctx id::ctx() const {
-  return isl::ctx(isl_id_get_ctx(ptr));
+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;
 }
 
-std::string id::name() const
+isl::val_list multi_val::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_get_name(get());
-  std::string tmp(res);
-  return tmp;
+  auto res = isl_multi_val_get_list(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-std::string id::get_name() const
+isl::val_list multi_val::get_list() const
 {
-  return name();
+  return list();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const id &obj)
+isl::multi_val multi_val::max(isl::multi_val multi2) const
 {
-  if (!obj.get())
+  if (!ptr || multi2.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_id_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_id_to_str(obj.get());
-  if (!str)
+  auto res = isl_multi_val_max(copy(), multi2.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::id_list
-id_list manage(__isl_take isl_id_list *ptr) {
-  if (!ptr)
+isl::multi_val multi_val::min(isl::multi_val multi2) const
+{
+  if (!ptr || multi2.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return id_list(ptr);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_val_min(copy(), multi2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
-id_list manage_copy(__isl_keep isl_id_list *ptr) {
+
+isl::multi_val multi_val::neg() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_id_list_get_ctx(ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_id_list_copy(ptr);
-  if (!ptr)
+  auto res = isl_multi_val_neg(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return id_list(ptr);
+  return manage(res);
 }
 
-id_list::id_list()
-    : ptr(nullptr) {}
-
-id_list::id_list(const id_list &obj)
-    : ptr(nullptr)
+bool multi_val::plain_is_equal(const isl::multi_val &multi2) const
 {
-  if (!obj.ptr)
+  if (!ptr || multi2.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_id_list_get_ctx(obj.ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = obj.copy();
-  if (!ptr)
+  auto res = isl_multi_val_plain_is_equal(get(), multi2.get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
+  return res;
 }
 
-id_list::id_list(__isl_take isl_id_list *ptr)
-    : ptr(ptr) {}
-
-id_list::id_list(isl::ctx ctx, int n)
+isl::multi_val multi_val::product(isl::multi_val multi2) const
 {
-  auto saved_ctx = ctx;
+  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_id_list_alloc(ctx.release(), n);
+  auto res = isl_multi_val_product(copy(), multi2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-id_list::id_list(isl::id el)
+isl::multi_val multi_val::range_product(isl::multi_val multi2) const
 {
-  if (el.is_null())
+  if (!ptr || multi2.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = el.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_id_list_from_id(el.release());
+  auto res = isl_multi_val_range_product(copy(), multi2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-id_list &id_list::operator=(id_list obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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);
 }
 
-id_list::~id_list() {
-  if (ptr)
-    isl_id_list_free(ptr);
+isl::id multi_val::get_range_tuple_id() const
+{
+  return range_tuple_id();
 }
 
-__isl_give isl_id_list *id_list::copy() const & {
-  return isl_id_list_copy(ptr);
+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_keep isl_id_list *id_list::get() const {
-  return ptr;
+isl::multi_val multi_val::scale(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_multi_val_scale_multi_val(copy(), mv.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-__isl_give isl_id_list *id_list::release() {
-  isl_id_list *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+isl::multi_val multi_val::scale(isl::val v) const
+{
+  if (!ptr || v.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_scale_val(copy(), v.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-bool id_list::is_null() const {
-  return ptr == nullptr;
+isl::multi_val multi_val::scale(long v) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->scale(isl::val(ctx(), v));
 }
 
-isl::ctx id_list::ctx() const {
-  return isl::ctx(isl_id_list_get_ctx(ptr));
+isl::multi_val multi_val::scale_down(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_multi_val_scale_down_multi_val(copy(), mv.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::id_list id_list::add(isl::id el) const
+isl::multi_val multi_val::scale_down(isl::val v) const
 {
-  if (!ptr || el.is_null())
+  if (!ptr || v.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_id_list_add(copy(), el.release());
+  auto res = isl_multi_val_scale_down_val(copy(), v.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::id_list id_list::add(const std::string &el) const
+isl::multi_val multi_val::scale_down(long v) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->add(isl::id(ctx(), el));
+  return this->scale_down(isl::val(ctx(), v));
 }
 
-isl::id_list id_list::clear() const
+isl::multi_val multi_val::set_at(int pos, isl::val el) const
 {
-  if (!ptr)
+  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_id_list_clear(copy());
+  auto res = isl_multi_val_set_at(copy(), pos, el.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::id_list id_list::concat(isl::id_list list2) const
+isl::multi_val multi_val::set_at(int pos, long el) const
 {
-  if (!ptr || list2.is_null())
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  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_id_list_concat(copy(), list2.release());
+  auto res = isl_multi_val_set_range_tuple_id(copy(), id.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::id_list id_list::drop(unsigned int first, unsigned int n) const
+isl::multi_val multi_val::set_range_tuple(const std::string &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_id_list_drop(copy(), first, n);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->set_range_tuple(isl::id(ctx(), id));
 }
 
-void id_list::foreach(const std::function<void(isl::id)> &fn) const
+unsigned multi_val::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);
-  struct fn_data {
-    std::function<void(isl::id)> func;
-    std::exception_ptr eptr;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_id *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_id_list_foreach(get(), fn_lambda, &fn_data);
-  if (fn_data.eptr)
-    std::rethrow_exception(fn_data.eptr);
+  auto res = isl_multi_val_size(get());
   if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return;
+  return res;
 }
 
-isl::id id_list::at(int index) const
+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_id_list_get_at(get(), index);
+  auto res = isl_multi_val_get_space(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::id id_list::get_at(int index) const
+isl::space multi_val::get_space() const
 {
-  return at(index);
+  return space();
 }
 
-isl::id_list id_list::insert(unsigned int pos, isl::id el) const
+isl::multi_val multi_val::sub(isl::multi_val multi2) const
 {
-  if (!ptr || el.is_null())
+  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_id_list_insert(copy(), pos, el.release());
+  auto res = isl_multi_val_sub(copy(), multi2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::id_list id_list::insert(unsigned int pos, const std::string &el) const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->insert(pos, isl::id(ctx(), el));
-}
-
-unsigned id_list::size() const
+isl::multi_val multi_val::zero(isl::space space)
 {
-  if (!ptr)
+  if (space.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = space.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_id_list_size(get());
-  if (res < 0)
+  auto res = isl_multi_val_zero(space.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const id_list &obj)
+inline std::ostream &operator<<(std::ostream &os, const multi_val &obj)
 {
   if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_id_list_get_ctx(obj.get());
+  auto saved_ctx = isl_multi_val_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_id_list_to_str(obj.get());
+  char *str = isl_multi_val_to_str(obj.get());
   if (!str)
     exception::throw_last_error(saved_ctx);
   os << str;
@@ -7318,1040 +16064,732 @@ inline std::ostream &operator<<(std::ostream &os, const id_list &obj)
   return os;
 }
 
-// implementations for isl::map
-map manage(__isl_take isl_map *ptr) {
+// implementations for isl::point
+point manage(__isl_take isl_point *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return map(ptr);
+  return point(ptr);
 }
-map manage_copy(__isl_keep isl_map *ptr) {
+point manage_copy(__isl_keep isl_point *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_map_get_ctx(ptr);
+  auto saved_ctx = isl_point_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_map_copy(ptr);
+  ptr = isl_point_copy(ptr);
   if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return map(ptr);
+  return point(ptr);
 }
 
-map::map()
+point::point()
     : ptr(nullptr) {}
 
-map::map(const map &obj)
+point::point(const point &obj)
     : ptr(nullptr)
 {
   if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_map_get_ctx(obj.ptr);
+  auto saved_ctx = isl_point_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::map(__isl_take isl_map *ptr)
+point::point(__isl_take isl_point *ptr)
     : ptr(ptr) {}
 
-map::map(isl::basic_map bmap)
-{
-  if (bmap.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = bmap.ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_map_from_basic_map(bmap.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-map::map(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_read_from_str(ctx.release(), str.c_str());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-map &map::operator=(map obj) {
+point &point::operator=(point obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-map::~map() {
+point::~point() {
   if (ptr)
-    isl_map_free(ptr);
+    isl_point_free(ptr);
 }
 
-__isl_give isl_map *map::copy() const & {
-  return isl_map_copy(ptr);
+__isl_give isl_point *point::copy() const & {
+  return isl_point_copy(ptr);
 }
 
-__isl_keep isl_map *map::get() const {
+__isl_keep isl_point *point::get() const {
   return ptr;
 }
 
-__isl_give isl_map *map::release() {
-  isl_map *tmp = ptr;
+__isl_give isl_point *point::release() {
+  isl_point *tmp = ptr;
   ptr = nullptr;
   return tmp;
 }
 
-bool map::is_null() const {
+bool point::is_null() const {
   return ptr == nullptr;
 }
 
-isl::ctx map::ctx() const {
-  return isl::ctx(isl_map_get_ctx(ptr));
+isl::ctx point::ctx() const {
+  return isl::ctx(isl_point_get_ctx(ptr));
 }
 
-isl::basic_map map::affine_hull() const
+isl::basic_set point::affine_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_affine_hull(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).affine_hull();
 }
 
-isl::map map::apply_domain(isl::map map2) const
+isl::basic_set point::apply(const isl::basic_map &bmap) const
 {
-  if (!ptr || map2.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_map_apply_domain(copy(), map2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).apply(bmap);
 }
 
-isl::map map::apply_range(isl::map map2) const
+isl::set point::apply(const isl::map &map) const
 {
-  if (!ptr || map2.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_map_apply_range(copy(), map2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).apply(map);
 }
 
-isl::set map::bind_domain(isl::multi_id tuple) const
+isl::union_set point::apply(const isl::union_map &umap) const
 {
-  if (!ptr || tuple.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_map_bind_domain(copy(), tuple.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).apply(umap);
 }
 
-isl::set map::bind_range(isl::multi_id tuple) const
+isl::pw_multi_aff point::as_pw_multi_aff() const
 {
-  if (!ptr || tuple.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_map_bind_range(copy(), tuple.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).as_pw_multi_aff();
 }
 
-isl::map map::coalesce() const
+isl::set point::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_map_coalesce(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).as_set();
 }
 
-isl::map map::complement() const
+isl::set point::bind(const isl::multi_id &tuple) 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_complement(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).bind(tuple);
 }
 
-isl::map map::curry() const
+isl::set point::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_map_curry(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).coalesce();
 }
 
-isl::set map::deltas() const
+isl::set point::complement() 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_deltas(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).complement();
 }
 
-isl::map map::detect_equalities() const
+isl::union_set point::compute_divs() 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_detect_equalities(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).compute_divs();
 }
 
-isl::set map::domain() const
+isl::basic_set point::detect_equalities() 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(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).detect_equalities();
 }
 
-isl::map map::domain_factor_domain() const
+isl::val point::dim_max_val(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_map_domain_factor_domain(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).dim_max_val(pos);
 }
 
-isl::map map::domain_factor_range() const
+isl::val point::dim_min_val(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_map_domain_factor_range(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).dim_min_val(pos);
 }
 
-isl::map map::domain_product(isl::map map2) const
+bool point::every_set(const std::function<bool(isl::set)> &test) const
 {
-  if (!ptr || map2.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_map_domain_product(copy(), map2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  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::map map::empty(isl::space space)
+isl::basic_set point::intersect(const isl::basic_set &bset2) const
 {
-  if (space.is_null())
+  if (!ptr)
     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_map_empty(space.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).intersect(bset2);
 }
 
-isl::map map::eq_at(isl::multi_pw_aff mpa) const
+isl::set point::intersect(const isl::set &set2) const
 {
-  if (!ptr || mpa.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_map_eq_at_multi_pw_aff(copy(), mpa.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).intersect(set2);
 }
 
-isl::map map::factor_domain() const
+isl::union_set point::intersect(const isl::union_set &uset2) 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_factor_domain(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).intersect(uset2);
 }
 
-isl::map map::factor_range() const
+isl::basic_set point::intersect_params(const isl::basic_set &bset2) 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_factor_range(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).intersect_params(bset2);
 }
 
-isl::map map::flatten() const
+isl::set point::intersect_params(const isl::set &params) 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_flatten(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).intersect_params(params);
 }
 
-isl::map map::flatten_domain() const
+bool point::involves_locals() 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_flatten_domain(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).involves_locals();
 }
 
-isl::map map::flatten_range() const
+bool point::is_disjoint(const isl::set &set2) 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_flatten_range(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).is_disjoint(set2);
 }
 
-void map::foreach_basic_map(const std::function<void(isl::basic_map)> &fn) const
+bool point::is_disjoint(const isl::union_set &uset2) 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::basic_map)> func;
-    std::exception_ptr eptr;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_basic_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_foreach_basic_map(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;
+  return isl::basic_set(*this).is_disjoint(uset2);
 }
 
-isl::fixed_box map::range_simple_fixed_box_hull() const
+bool point::is_empty() 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);
+  return isl::basic_set(*this).is_empty();
 }
 
-isl::fixed_box map::get_range_simple_fixed_box_hull() const
+bool point::is_equal(const isl::basic_set &bset2) const
 {
-  return range_simple_fixed_box_hull();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_equal(bset2);
 }
 
-isl::space map::space() const
+bool point::is_equal(const isl::set &set2) 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);
+  return isl::basic_set(*this).is_equal(set2);
 }
 
-isl::space map::get_space() const
+bool point::is_equal(const isl::union_set &uset2) const
 {
-  return space();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_equal(uset2);
 }
 
-isl::map map::gist(isl::map context) const
+bool point::is_singleton() const
 {
-  if (!ptr || context.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_map_gist(copy(), context.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).is_singleton();
 }
 
-isl::map map::gist_domain(isl::set context) const
+bool point::is_strict_subset(const isl::set &set2) const
 {
-  if (!ptr || context.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_map_gist_domain(copy(), context.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).is_strict_subset(set2);
 }
 
-isl::map map::intersect(isl::map map2) const
+bool point::is_strict_subset(const isl::union_set &uset2) const
 {
-  if (!ptr || map2.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_map_intersect(copy(), map2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).is_strict_subset(uset2);
 }
 
-isl::map map::intersect_domain(isl::set set) const
+bool point::is_subset(const isl::basic_set &bset2) const
 {
-  if (!ptr || set.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_map_intersect_domain(copy(), set.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).is_subset(bset2);
 }
 
-isl::map map::intersect_domain_factor_domain(isl::map factor) const
+bool point::is_subset(const isl::set &set2) const
 {
-  if (!ptr || factor.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_map_intersect_domain_factor_domain(copy(), factor.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).is_subset(set2);
 }
 
-isl::map map::intersect_domain_factor_range(isl::map factor) const
+bool point::is_subset(const isl::union_set &uset2) const
 {
-  if (!ptr || factor.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_map_intersect_domain_factor_range(copy(), factor.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).is_subset(uset2);
 }
 
-isl::map map::intersect_params(isl::set params) const
+bool point::is_wrapping() const
 {
-  if (!ptr || params.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_map_intersect_params(copy(), params.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).is_wrapping();
 }
 
-isl::map map::intersect_range(isl::set set) const
+bool point::isa_set() const
 {
-  if (!ptr || set.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_map_intersect_range(copy(), set.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).isa_set();
 }
 
-isl::map map::intersect_range_factor_domain(isl::map factor) const
+isl::set point::lexmax() const
 {
-  if (!ptr || factor.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_map_intersect_range_factor_domain(copy(), factor.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).lexmax();
 }
 
-isl::map map::intersect_range_factor_range(isl::map factor) const
+isl::pw_multi_aff point::lexmax_pw_multi_aff() const
 {
-  if (!ptr || factor.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_map_intersect_range_factor_range(copy(), factor.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).lexmax_pw_multi_aff();
 }
 
-bool map::is_bijective() const
+isl::set point::lexmin() 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_is_bijective(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::basic_set(*this).lexmin();
 }
 
-bool map::is_disjoint(const isl::map &map2) const
+isl::pw_multi_aff point::lexmin_pw_multi_aff() const
 {
-  if (!ptr || map2.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_map_is_disjoint(get(), map2.get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::basic_set(*this).lexmin_pw_multi_aff();
 }
 
-bool map::is_empty() const
+isl::set point::lower_bound(const isl::multi_pw_aff &lower) 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_is_empty(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::basic_set(*this).lower_bound(lower);
 }
 
-bool map::is_equal(const isl::map &map2) const
+isl::set point::lower_bound(const isl::multi_val &lower) const
 {
-  if (!ptr || map2.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_map_is_equal(get(), map2.get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::basic_set(*this).lower_bound(lower);
 }
 
-bool map::is_injective() const
+isl::multi_pw_aff point::max_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_map_is_injective(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::basic_set(*this).max_multi_pw_aff();
 }
 
-bool map::is_single_valued() const
+isl::val point::max_val(const isl::aff &obj) 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_is_single_valued(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::basic_set(*this).max_val(obj);
 }
 
-bool map::is_strict_subset(const isl::map &map2) const
+isl::multi_pw_aff point::min_multi_pw_aff() const
 {
-  if (!ptr || map2.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_map_is_strict_subset(get(), map2.get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::basic_set(*this).min_multi_pw_aff();
 }
 
-bool map::is_subset(const isl::map &map2) const
+isl::val point::min_val(const isl::aff &obj) const
 {
-  if (!ptr || map2.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_map_is_subset(get(), map2.get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::basic_set(*this).min_val(obj);
 }
 
-isl::map map::lex_ge_at(isl::multi_pw_aff mpa) const
+isl::multi_val point::multi_val() const
 {
-  if (!ptr || mpa.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_map_lex_ge_at_multi_pw_aff(copy(), mpa.release());
+  auto res = isl_point_get_multi_val(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::map map::lex_gt_at(isl::multi_pw_aff mpa) const
+isl::multi_val point::get_multi_val() const
 {
-  if (!ptr || mpa.is_null())
+  return multi_val();
+}
+
+isl::basic_set point::params() 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_lex_gt_at_multi_pw_aff(copy(), mpa.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).params();
 }
 
-isl::map map::lex_le_at(isl::multi_pw_aff mpa) const
+isl::multi_val point::plain_multi_val_if_fixed() const
 {
-  if (!ptr || mpa.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_map_lex_le_at_multi_pw_aff(copy(), mpa.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).plain_multi_val_if_fixed();
 }
 
-isl::map map::lex_lt_at(isl::multi_pw_aff mpa) const
+isl::basic_set point::polyhedral_hull() const
 {
-  if (!ptr || mpa.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_map_lex_lt_at_multi_pw_aff(copy(), mpa.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).polyhedral_hull();
 }
 
-isl::map map::lexmax() const
+isl::set point::preimage(const isl::multi_aff &ma) 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_lexmax(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).preimage(ma);
 }
 
-isl::pw_multi_aff map::lexmax_pw_multi_aff() const
+isl::set point::preimage(const isl::multi_pw_aff &mpa) 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_lexmax_pw_multi_aff(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).preimage(mpa);
 }
 
-isl::map map::lexmin() const
+isl::set point::preimage(const isl::pw_multi_aff &pma) 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_lexmin(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).preimage(pma);
 }
 
-isl::pw_multi_aff map::lexmin_pw_multi_aff() const
+isl::union_set point::preimage(const isl::union_pw_multi_aff &upma) 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_lexmin_pw_multi_aff(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).preimage(upma);
 }
 
-isl::map map::lower_bound(isl::multi_pw_aff lower) const
+isl::set point::product(const isl::set &set2) const
 {
-  if (!ptr || lower.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_map_lower_bound_multi_pw_aff(copy(), lower.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).product(set2);
 }
 
-isl::multi_pw_aff map::max_multi_pw_aff() const
+isl::set point::project_out_all_params() 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_max_multi_pw_aff(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).project_out_all_params();
 }
 
-isl::multi_pw_aff map::min_multi_pw_aff() const
+isl::set point::project_out_param(const isl::id &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_min_multi_pw_aff(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).project_out_param(id);
 }
 
-isl::basic_map map::polyhedral_hull() const
+isl::set point::project_out_param(const std::string &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_polyhedral_hull(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->project_out_param(isl::id(ctx(), id));
 }
 
-isl::map map::preimage_domain(isl::multi_aff ma) const
+isl::set point::project_out_param(const isl::id_list &list) const
 {
-  if (!ptr || ma.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_map_preimage_domain_multi_aff(copy(), ma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).project_out_param(list);
 }
 
-isl::map map::preimage_domain(isl::multi_pw_aff mpa) const
+isl::pw_multi_aff point::pw_multi_aff_on_domain(const isl::multi_val &mv) const
 {
-  if (!ptr || mpa.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_map_preimage_domain_multi_pw_aff(copy(), mpa.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).pw_multi_aff_on_domain(mv);
 }
 
-isl::map map::preimage_domain(isl::pw_multi_aff pma) const
+isl::basic_set point::sample() const
 {
-  if (!ptr || pma.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_map_preimage_domain_pw_multi_aff(copy(), pma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).sample();
 }
 
-isl::map map::preimage_range(isl::multi_aff ma) const
+isl::point point::sample_point() const
 {
-  if (!ptr || ma.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_map_preimage_range_multi_aff(copy(), ma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).sample_point();
 }
 
-isl::map map::preimage_range(isl::pw_multi_aff pma) const
+isl::fixed_box point::simple_fixed_box_hull() const
 {
-  if (!ptr || pma.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_map_preimage_range_pw_multi_aff(copy(), pma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).simple_fixed_box_hull();
 }
 
-isl::map map::product(isl::map map2) const
+isl::space point::space() const
 {
-  if (!ptr || map2.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_map_product(copy(), map2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).space();
 }
 
-isl::map map::project_out_all_params() const
+isl::val point::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_map_project_out_all_params(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).stride(pos);
 }
 
-isl::set map::range() const
+isl::set point::subtract(const isl::set &set2) 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(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).subtract(set2);
 }
 
-isl::map map::range_factor_domain() const
+isl::union_set point::subtract(const isl::union_set &uset2) 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_factor_domain(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).subtract(uset2);
 }
 
-isl::map map::range_factor_range() const
+isl::union_set_list point::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_range_factor_range(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).to_list();
 }
 
-isl::map map::range_product(isl::map map2) const
+isl::set point::to_set() const
 {
-  if (!ptr || map2.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_map_range_product(copy(), map2.release());
+  auto res = isl_point_to_set(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::map map::range_reverse() const
+isl::union_set point::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_map_range_reverse(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).to_union_set();
 }
 
-isl::map map::reverse() const
+isl::map point::translation() 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_reverse(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).translation();
 }
 
-isl::basic_map map::sample() const
+unsigned point::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_sample(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).tuple_dim();
 }
 
-isl::map map::subtract(isl::map map2) const
+isl::set point::unbind_params(const isl::multi_id &tuple) const
 {
-  if (!ptr || map2.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_map_subtract(copy(), map2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).unbind_params(tuple);
 }
 
-isl::map map::uncurry() const
+isl::map point::unbind_params_insert_domain(const isl::multi_id &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_map_uncurry(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).unbind_params_insert_domain(domain);
 }
 
-isl::map map::unite(isl::map map2) const
+isl::set point::unite(const isl::basic_set &bset2) const
 {
-  if (!ptr || map2.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_map_union(copy(), map2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).unite(bset2);
 }
 
-isl::map map::universe(isl::space space)
+isl::set point::unite(const isl::set &set2) const
 {
-  if (space.is_null())
+  if (!ptr)
     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_map_universe(space.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).unite(set2);
 }
 
-isl::basic_map map::unshifted_simple_hull() const
+isl::union_set point::unite(const isl::union_set &uset2) 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_unshifted_simple_hull(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).unite(uset2);
 }
 
-isl::map map::upper_bound(isl::multi_pw_aff upper) const
+isl::basic_set point::unshifted_simple_hull() const
 {
-  if (!ptr || upper.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_map_upper_bound_multi_pw_aff(copy(), upper.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  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 map::wrap() const
+isl::set point::upper_bound(const isl::multi_pw_aff &upper) 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_wrap(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).upper_bound(upper);
 }
 
-isl::map map::zip() const
+isl::set point::upper_bound(const isl::multi_val &upper) 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_zip(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::basic_set(*this).upper_bound(upper);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const map &obj)
+inline std::ostream &operator<<(std::ostream &os, const point &obj)
 {
   if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_map_get_ctx(obj.get());
+  auto saved_ctx = isl_point_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_map_to_str(obj.get());
+  char *str = isl_point_to_str(obj.get());
   if (!str)
     exception::throw_last_error(saved_ctx);
   os << str;
@@ -8359,1482 +16797,1290 @@ inline std::ostream &operator<<(std::ostream &os, const map &obj)
   return os;
 }
 
-// implementations for isl::multi_aff
-multi_aff manage(__isl_take isl_multi_aff *ptr) {
+// implementations for isl::pw_aff
+pw_aff manage(__isl_take isl_pw_aff *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return multi_aff(ptr);
+  return pw_aff(ptr);
 }
-multi_aff manage_copy(__isl_keep isl_multi_aff *ptr) {
+pw_aff manage_copy(__isl_keep isl_pw_aff *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_aff_get_ctx(ptr);
+  auto saved_ctx = isl_pw_aff_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_multi_aff_copy(ptr);
+  ptr = isl_pw_aff_copy(ptr);
   if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return multi_aff(ptr);
+  return pw_aff(ptr);
 }
 
-multi_aff::multi_aff()
+pw_aff::pw_aff()
     : ptr(nullptr) {}
 
-multi_aff::multi_aff(const multi_aff &obj)
+pw_aff::pw_aff(const pw_aff &obj)
     : ptr(nullptr)
 {
   if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_aff_get_ctx(obj.ptr);
+  auto saved_ctx = isl_pw_aff_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);
 }
 
-multi_aff::multi_aff(__isl_take isl_multi_aff *ptr)
+pw_aff::pw_aff(__isl_take isl_pw_aff *ptr)
     : ptr(ptr) {}
 
-multi_aff::multi_aff(isl::aff aff)
+pw_aff::pw_aff(isl::aff aff)
 {
   if (aff.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
   auto saved_ctx = aff.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_aff_from_aff(aff.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-multi_aff::multi_aff(isl::space space, isl::aff_list list)
-{
-  if (space.is_null() || list.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_from_aff_list(space.release(), list.release());
+  auto res = isl_pw_aff_from_aff(aff.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   ptr = res;
 }
 
-multi_aff::multi_aff(isl::ctx ctx, const std::string &str)
+pw_aff::pw_aff(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_multi_aff_read_from_str(ctx.release(), str.c_str());
+  auto res = isl_pw_aff_read_from_str(ctx.release(), str.c_str());
   if (!res)
     exception::throw_last_error(saved_ctx);
   ptr = res;
 }
 
-multi_aff &multi_aff::operator=(multi_aff obj) {
+pw_aff &pw_aff::operator=(pw_aff obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-multi_aff::~multi_aff() {
+pw_aff::~pw_aff() {
   if (ptr)
-    isl_multi_aff_free(ptr);
+    isl_pw_aff_free(ptr);
 }
 
-__isl_give isl_multi_aff *multi_aff::copy() const & {
-  return isl_multi_aff_copy(ptr);
+__isl_give isl_pw_aff *pw_aff::copy() const & {
+  return isl_pw_aff_copy(ptr);
 }
 
-__isl_keep isl_multi_aff *multi_aff::get() const {
+__isl_keep isl_pw_aff *pw_aff::get() const {
   return ptr;
 }
 
-__isl_give isl_multi_aff *multi_aff::release() {
-  isl_multi_aff *tmp = ptr;
+__isl_give isl_pw_aff *pw_aff::release() {
+  isl_pw_aff *tmp = ptr;
   ptr = nullptr;
   return tmp;
 }
 
-bool multi_aff::is_null() const {
+bool pw_aff::is_null() const {
   return ptr == nullptr;
 }
 
-isl::ctx multi_aff::ctx() const {
-  return isl::ctx(isl_multi_aff_get_ctx(ptr));
+isl::ctx pw_aff::ctx() const {
+  return isl::ctx(isl_pw_aff_get_ctx(ptr));
 }
 
-isl::multi_aff multi_aff::add(isl::multi_aff multi2) const
+isl::multi_pw_aff pw_aff::add(const isl::multi_pw_aff &multi2) const
 {
-  if (!ptr || multi2.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_multi_aff_add(copy(), multi2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_multi_aff(*this).add(multi2);
 }
 
-isl::multi_aff multi_aff::add_constant(isl::multi_val mv) const
+isl::multi_union_pw_aff pw_aff::add(const isl::multi_union_pw_aff &multi2) const
 {
-  if (!ptr || mv.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_multi_aff_add_constant_multi_val(copy(), mv.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).add(multi2);
 }
 
-isl::multi_aff multi_aff::add_constant(isl::val v) const
+isl::pw_aff pw_aff::add(isl::pw_aff pwaff2) const
 {
-  if (!ptr || v.is_null())
+  if (!ptr || pwaff2.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_add_constant_val(copy(), v.release());
+  auto res = isl_pw_aff_add(copy(), pwaff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_aff multi_aff::add_constant(long v) const
+isl::pw_multi_aff pw_aff::add(const isl::pw_multi_aff &pma2) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->add_constant(isl::val(ctx(), v));
+  return isl::pw_multi_aff(*this).add(pma2);
 }
 
-isl::basic_set multi_aff::bind(isl::multi_id tuple) const
+isl::union_pw_aff pw_aff::add(const isl::union_pw_aff &upa2) const
 {
-  if (!ptr || tuple.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_multi_aff_bind(copy(), tuple.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).add(upa2);
 }
 
-isl::multi_aff multi_aff::bind_domain(isl::multi_id tuple) const
+isl::union_pw_multi_aff pw_aff::add(const isl::union_pw_multi_aff &upma2) const
 {
-  if (!ptr || tuple.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_multi_aff_bind_domain(copy(), tuple.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).add(upma2);
 }
 
-isl::multi_aff multi_aff::bind_domain_wrapped_domain(isl::multi_id tuple) const
+isl::pw_aff pw_aff::add(const isl::aff &pwaff2) const
 {
-  if (!ptr || tuple.is_null())
+  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())
     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_bind_domain_wrapped_domain(copy(), tuple.release());
+  auto res = isl_pw_aff_add_constant_val(copy(), v.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_aff multi_aff::domain_map(isl::space space)
+isl::pw_aff pw_aff::add_constant(long v) const
 {
-  if (space.is_null())
+  if (!ptr)
     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);
+  return this->add_constant(isl::val(ctx(), v));
 }
 
-isl::multi_aff multi_aff::flat_range_product(isl::multi_aff multi2) const
+isl::pw_multi_aff pw_aff::add_constant(const isl::multi_val &mv) const
 {
-  if (!ptr || multi2.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_multi_aff_flat_range_product(copy(), multi2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_multi_aff(*this).add_constant(mv);
 }
 
-isl::multi_aff multi_aff::floor() const
+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__);
-  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);
+  return isl::union_pw_aff(*this).apply(upma2);
 }
 
-isl::aff multi_aff::at(int pos) const
+isl::aff pw_aff::as_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_get_at(get(), pos);
+  auto res = isl_pw_aff_as_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::aff multi_aff::get_at(int pos) const
-{
-  return at(pos);
-}
-
-isl::multi_val multi_aff::constant_multi_val() const
+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_multi_aff_get_constant_multi_val(get());
+  auto res = isl_pw_aff_as_map(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_val multi_aff::get_constant_multi_val() const
-{
-  return constant_multi_val();
-}
-
-isl::aff_list multi_aff::list() const
+isl::multi_aff 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_aff_get_list(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_multi_aff(*this).as_multi_aff();
 }
 
-isl::aff_list multi_aff::get_list() const
+isl::multi_union_pw_aff pw_aff::as_multi_union_pw_aff() const
 {
-  return list();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).as_multi_union_pw_aff();
 }
 
-isl::space multi_aff::space() const
+isl::pw_multi_aff pw_aff::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_multi_aff_get_space(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).as_pw_multi_aff();
 }
 
-isl::space multi_aff::get_space() const
+isl::set pw_aff::as_set() const
 {
-  return space();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).as_set();
 }
 
-isl::multi_aff multi_aff::gist(isl::set context) const
+isl::union_map pw_aff::as_union_map() const
 {
-  if (!ptr || context.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_multi_aff_gist(copy(), context.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).as_union_map();
 }
 
-isl::multi_aff multi_aff::identity() const
+isl::pw_aff 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_aff_identity_multi_aff(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_multi_aff(*this).at(pos);
 }
 
-isl::multi_aff multi_aff::identity_on_domain(isl::space space)
+isl::set pw_aff::bind(const isl::multi_id &tuple) const
 {
-  if (space.is_null())
+  if (!ptr)
     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_identity_on_domain_space(space.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_pw_aff(*this).bind(tuple);
 }
 
-isl::multi_aff multi_aff::insert_domain(isl::space domain) const
+isl::set pw_aff::bind(isl::id id) const
 {
-  if (!ptr || domain.is_null())
+  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_insert_domain(copy(), domain.release());
+  auto res = isl_pw_aff_bind_id(copy(), id.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool multi_aff::involves_locals() const
+isl::set pw_aff::bind(const std::string &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_involves_locals(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return this->bind(isl::id(ctx(), id));
 }
 
-bool multi_aff::involves_nan() const
+isl::pw_aff pw_aff::bind_domain(isl::multi_id tuple) const
 {
-  if (!ptr)
+  if (!ptr || tuple.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_involves_nan(get());
-  if (res < 0)
+  auto res = isl_pw_aff_bind_domain(copy(), tuple.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-isl::multi_aff multi_aff::neg() const
+isl::pw_aff pw_aff::bind_domain_wrapped_domain(isl::multi_id tuple) const
 {
-  if (!ptr)
+  if (!ptr || tuple.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_neg(copy());
+  auto res = isl_pw_aff_bind_domain_wrapped_domain(copy(), tuple.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool multi_aff::plain_is_equal(const isl::multi_aff &multi2) const
+isl::pw_aff pw_aff::ceil() const
 {
-  if (!ptr || multi2.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_multi_aff_plain_is_equal(get(), multi2.get());
-  if (res < 0)
+  auto res = isl_pw_aff_ceil(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-isl::multi_aff multi_aff::product(isl::multi_aff multi2) const
+isl::pw_aff pw_aff::coalesce() const
 {
-  if (!ptr || multi2.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_multi_aff_product(copy(), multi2.release());
+  auto res = isl_pw_aff_coalesce(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_aff multi_aff::pullback(isl::multi_aff ma2) const
+isl::pw_aff pw_aff::cond(isl::pw_aff pwaff_true, isl::pw_aff pwaff_false) const
 {
-  if (!ptr || ma2.is_null())
+  if (!ptr || pwaff_true.is_null() || pwaff_false.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_pullback_multi_aff(copy(), ma2.release());
+  auto res = isl_pw_aff_cond(copy(), pwaff_true.release(), pwaff_false.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_aff multi_aff::range_map(isl::space space)
+isl::pw_aff pw_aff::div(isl::pw_aff pa2) const
 {
-  if (space.is_null())
+  if (!ptr || pa2.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_aff_range_map(space.release());
+  auto res = isl_pw_aff_div(copy(), pa2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_aff multi_aff::range_product(isl::multi_aff multi2) const
+isl::set pw_aff::domain() const
 {
-  if (!ptr || multi2.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_multi_aff_range_product(copy(), multi2.release());
+  auto res = isl_pw_aff_domain(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_aff multi_aff::scale(isl::multi_val mv) const
+isl::set pw_aff::eq_set(isl::pw_aff pwaff2) const
 {
-  if (!ptr || mv.is_null())
+  if (!ptr || pwaff2.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_scale_multi_val(copy(), mv.release());
+  auto res = isl_pw_aff_eq_set(copy(), pwaff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_aff multi_aff::scale(isl::val v) const
+isl::val pw_aff::eval(isl::point pnt) const
 {
-  if (!ptr || v.is_null())
+  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_multi_aff_scale_val(copy(), v.release());
+  auto res = isl_pw_aff_eval(copy(), pnt.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_aff multi_aff::scale(long v) const
+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 this->scale(isl::val(ctx(), v));
+  return isl::union_pw_aff(*this).extract_pw_multi_aff(space);
 }
 
-isl::multi_aff multi_aff::scale_down(isl::multi_val mv) const
+isl::multi_pw_aff pw_aff::flat_range_product(const isl::multi_pw_aff &multi2) const
 {
-  if (!ptr || mv.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_multi_aff_scale_down_multi_val(copy(), mv.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_multi_aff(*this).flat_range_product(multi2);
 }
 
-isl::multi_aff multi_aff::scale_down(isl::val v) const
+isl::multi_union_pw_aff pw_aff::flat_range_product(const isl::multi_union_pw_aff &multi2) const
 {
-  if (!ptr || v.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_multi_aff_scale_down_val(copy(), v.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).flat_range_product(multi2);
 }
 
-isl::multi_aff multi_aff::scale_down(long v) const
+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 this->scale_down(isl::val(ctx(), v));
+  return isl::pw_multi_aff(*this).flat_range_product(pma2);
 }
 
-isl::multi_aff multi_aff::set_at(int pos, isl::aff el) const
+isl::union_pw_multi_aff pw_aff::flat_range_product(const isl::union_pw_multi_aff &upma2) const
 {
-  if (!ptr || el.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_multi_aff_set_at(copy(), pos, el.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).flat_range_product(upma2);
 }
 
-unsigned multi_aff::size() const
+isl::pw_aff pw_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_size(get());
-  if (res < 0)
+  auto res = isl_pw_aff_floor(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-isl::multi_aff multi_aff::sub(isl::multi_aff multi2) const
+void pw_aff::foreach_piece(const std::function<void(isl::set, isl::multi_aff)> &fn) const
 {
-  if (!ptr || multi2.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_multi_aff_sub(copy(), multi2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_multi_aff(*this).foreach_piece(fn);
 }
 
-isl::multi_aff multi_aff::unbind_params_insert_domain(isl::multi_id domain) const
+isl::set pw_aff::ge_set(isl::pw_aff pwaff2) const
 {
-  if (!ptr || domain.is_null())
+  if (!ptr || pwaff2.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_unbind_params_insert_domain(copy(), domain.release());
+  auto res = isl_pw_aff_ge_set(copy(), pwaff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_aff multi_aff::zero(isl::space space)
+isl::pw_aff pw_aff::gist(isl::set context) const
 {
-  if (space.is_null())
+  if (!ptr || context.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_aff_zero(space.release());
+  auto res = isl_pw_aff_gist(copy(), context.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const multi_aff &obj)
+isl::union_pw_aff pw_aff::gist(const isl::union_set &context) const
 {
-  if (!obj.get())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_aff_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_multi_aff_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
-}
-
-// implementations for isl::multi_id
-multi_id manage(__isl_take isl_multi_id *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return multi_id(ptr);
+  return isl::union_pw_aff(*this).gist(context);
 }
-multi_id manage_copy(__isl_keep isl_multi_id *ptr) {
+
+isl::pw_aff pw_aff::gist(const isl::basic_set &context) const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_id_get_ctx(ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_multi_id_copy(ptr);
-  if (!ptr)
-    exception::throw_last_error(saved_ctx);
-  return multi_id(ptr);
+  return this->gist(isl::set(context));
 }
 
-multi_id::multi_id()
-    : ptr(nullptr) {}
-
-multi_id::multi_id(const multi_id &obj)
-    : ptr(nullptr)
+isl::pw_aff pw_aff::gist(const isl::point &context) const
 {
-  if (!obj.ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_id_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);
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(context));
 }
 
-multi_id::multi_id(__isl_take isl_multi_id *ptr)
-    : ptr(ptr) {}
-
-multi_id::multi_id(isl::space space, isl::id_list list)
+isl::set pw_aff::gt_set(isl::pw_aff pwaff2) const
 {
-  if (space.is_null() || list.is_null())
+  if (!ptr || pwaff2.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_id_from_id_list(space.release(), list.release());
+  auto res = isl_pw_aff_gt_set(copy(), pwaff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-multi_id::multi_id(isl::ctx ctx, const std::string &str)
+bool pw_aff::has_range_tuple_id() const
 {
-  auto saved_ctx = ctx;
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_id_read_from_str(ctx.release(), str.c_str());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-multi_id &multi_id::operator=(multi_id obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-multi_id::~multi_id() {
-  if (ptr)
-    isl_multi_id_free(ptr);
-}
-
-__isl_give isl_multi_id *multi_id::copy() const & {
-  return isl_multi_id_copy(ptr);
-}
-
-__isl_keep isl_multi_id *multi_id::get() const {
-  return ptr;
-}
-
-__isl_give isl_multi_id *multi_id::release() {
-  isl_multi_id *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
-}
-
-bool multi_id::is_null() const {
-  return ptr == nullptr;
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).has_range_tuple_id();
 }
 
-isl::ctx multi_id::ctx() const {
-  return isl::ctx(isl_multi_id_get_ctx(ptr));
+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::multi_id multi_id::flat_range_product(isl::multi_id multi2) const
+isl::pw_aff pw_aff::insert_domain(isl::space domain) const
 {
-  if (!ptr || multi2.is_null())
+  if (!ptr || domain.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());
+  auto res = isl_pw_aff_insert_domain(copy(), domain.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::id multi_id::at(int pos) const
+isl::pw_aff pw_aff::intersect_domain(isl::set set) const
 {
-  if (!ptr)
+  if (!ptr || set.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_get_at(get(), pos);
+  auto res = isl_pw_aff_intersect_domain(copy(), set.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::id multi_id::get_at(int pos) const
-{
-  return at(pos);
-}
-
-isl::id_list multi_id::list() const
+isl::union_pw_aff pw_aff::intersect_domain(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_multi_id_get_list(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).intersect_domain(space);
 }
 
-isl::id_list multi_id::get_list() const
+isl::union_pw_aff pw_aff::intersect_domain(const isl::union_set &uset) const
 {
-  return list();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).intersect_domain(uset);
 }
 
-isl::space multi_id::space() const
+isl::pw_aff pw_aff::intersect_domain(const isl::basic_set &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_id_get_space(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->intersect_domain(isl::set(set));
 }
 
-isl::space multi_id::get_space() const
+isl::pw_aff pw_aff::intersect_domain(const isl::point &set) const
 {
-  return space();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_domain(isl::set(set));
 }
 
-bool multi_id::plain_is_equal(const isl::multi_id &multi2) const
+isl::union_pw_aff pw_aff::intersect_domain_wrapped_domain(const isl::union_set &uset) const
 {
-  if (!ptr || multi2.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_multi_id_plain_is_equal(get(), multi2.get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::union_pw_aff(*this).intersect_domain_wrapped_domain(uset);
 }
 
-isl::multi_id multi_id::range_product(isl::multi_id multi2) const
+isl::union_pw_aff pw_aff::intersect_domain_wrapped_range(const isl::union_set &uset) const
 {
-  if (!ptr || multi2.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_multi_id_range_product(copy(), multi2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).intersect_domain_wrapped_range(uset);
 }
 
-isl::multi_id multi_id::set_at(int pos, isl::id el) const
+isl::pw_aff pw_aff::intersect_params(isl::set set) const
 {
-  if (!ptr || el.is_null())
+  if (!ptr || set.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_set_at(copy(), pos, el.release());
+  auto res = isl_pw_aff_intersect_params(copy(), set.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_id multi_id::set_at(int pos, const std::string &el) const
+bool pw_aff::involves_locals() const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->set_at(pos, isl::id(ctx(), el));
+  return isl::pw_multi_aff(*this).involves_locals();
 }
 
-unsigned multi_id::size() const
+bool pw_aff::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_id_size(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::multi_pw_aff(*this).involves_nan();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const multi_id &obj)
+bool pw_aff::involves_param(const isl::id &id) const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_id_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_multi_id_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return isl::pw_multi_aff(*this).involves_param(id);
 }
 
-// implementations for isl::multi_pw_aff
-multi_pw_aff manage(__isl_take isl_multi_pw_aff *ptr) {
+bool pw_aff::involves_param(const std::string &id) const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return multi_pw_aff(ptr);
+  return this->involves_param(isl::id(ctx(), id));
 }
-multi_pw_aff manage_copy(__isl_keep isl_multi_pw_aff *ptr) {
+
+bool pw_aff::involves_param(const isl::id_list &list) const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_pw_aff_get_ctx(ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_multi_pw_aff_copy(ptr);
-  if (!ptr)
-    exception::throw_last_error(saved_ctx);
-  return multi_pw_aff(ptr);
+  return isl::pw_multi_aff(*this).involves_param(list);
 }
 
-multi_pw_aff::multi_pw_aff()
-    : ptr(nullptr) {}
-
-multi_pw_aff::multi_pw_aff(const multi_pw_aff &obj)
-    : ptr(nullptr)
+bool pw_aff::isa_aff() const
 {
-  if (!obj.ptr)
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_pw_aff_get_ctx(obj.ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = obj.copy();
-  if (!ptr)
+  auto res = isl_pw_aff_isa_aff(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
+  return res;
 }
 
-multi_pw_aff::multi_pw_aff(__isl_take isl_multi_pw_aff *ptr)
-    : ptr(ptr) {}
+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();
+}
 
-multi_pw_aff::multi_pw_aff(isl::aff aff)
+bool pw_aff::isa_pw_multi_aff() const
 {
-  if (aff.is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = aff.ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_pw_aff_from_aff(aff.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return isl::union_pw_aff(*this).isa_pw_multi_aff();
 }
 
-multi_pw_aff::multi_pw_aff(isl::multi_aff ma)
+isl::set pw_aff::le_set(isl::pw_aff pwaff2) const
 {
-  if (ma.is_null())
+  if (!ptr || pwaff2.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ma.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_pw_aff_from_multi_aff(ma.release());
+  auto res = isl_pw_aff_le_set(copy(), pwaff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-multi_pw_aff::multi_pw_aff(isl::pw_aff pa)
+isl::pw_aff_list pw_aff::list() const
 {
-  if (pa.is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = pa.ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_pw_aff_from_pw_aff(pa.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return isl::multi_pw_aff(*this).list();
 }
 
-multi_pw_aff::multi_pw_aff(isl::space space, isl::pw_aff_list list)
+isl::set pw_aff::lt_set(isl::pw_aff pwaff2) const
 {
-  if (space.is_null() || list.is_null())
+  if (!ptr || pwaff2.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_pw_aff_from_pw_aff_list(space.release(), list.release());
+  auto res = isl_pw_aff_lt_set(copy(), pwaff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-multi_pw_aff::multi_pw_aff(isl::pw_multi_aff pma)
+isl::multi_pw_aff pw_aff::max(const isl::multi_pw_aff &multi2) const
 {
-  if (pma.is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = pma.ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_pw_aff_from_pw_multi_aff(pma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return isl::pw_multi_aff(*this).max(multi2);
 }
 
-multi_pw_aff::multi_pw_aff(isl::ctx ctx, const std::string &str)
+isl::pw_aff pw_aff::max(isl::pw_aff pwaff2) const
 {
-  auto saved_ctx = ctx;
+  if (!ptr || pwaff2.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_read_from_str(ctx.release(), str.c_str());
+  auto res = isl_pw_aff_max(copy(), pwaff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-multi_pw_aff &multi_pw_aff::operator=(multi_pw_aff obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+  return manage(res);
 }
 
-multi_pw_aff::~multi_pw_aff() {
-  if (ptr)
-    isl_multi_pw_aff_free(ptr);
+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_give isl_multi_pw_aff *multi_pw_aff::copy() const & {
-  return isl_multi_pw_aff_copy(ptr);
+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_keep isl_multi_pw_aff *multi_pw_aff::get() const {
-  return ptr;
+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_give isl_multi_pw_aff *multi_pw_aff::release() {
-  isl_multi_pw_aff *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+isl::pw_aff pw_aff::min(isl::pw_aff pwaff2) const
+{
+  if (!ptr || pwaff2.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_aff_min(copy(), pwaff2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-bool multi_pw_aff::is_null() const {
-  return ptr == nullptr;
+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::ctx multi_pw_aff::ctx() const {
-  return isl::ctx(isl_multi_pw_aff_get_ctx(ptr));
+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::multi_pw_aff multi_pw_aff::add(isl::multi_pw_aff multi2) const
+isl::pw_aff pw_aff::mod(isl::val mod) const
 {
-  if (!ptr || multi2.is_null())
+  if (!ptr || mod.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_add(copy(), multi2.release());
+  auto res = isl_pw_aff_mod_val(copy(), mod.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff multi_pw_aff::add_constant(isl::multi_val mv) const
+isl::pw_aff pw_aff::mod(long mod) const
 {
-  if (!ptr || mv.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_multi_pw_aff_add_constant_multi_val(copy(), mv.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->mod(isl::val(ctx(), mod));
 }
 
-isl::multi_pw_aff multi_pw_aff::add_constant(isl::val v) const
+isl::pw_aff pw_aff::mul(isl::pw_aff pwaff2) const
 {
-  if (!ptr || v.is_null())
+  if (!ptr || pwaff2.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_add_constant_val(copy(), v.release());
+  auto res = isl_pw_aff_mul(copy(), pwaff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff multi_pw_aff::add_constant(long v) const
+unsigned pw_aff::n_piece() const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->add_constant(isl::val(ctx(), v));
+  return isl::pw_multi_aff(*this).n_piece();
 }
 
-isl::set multi_pw_aff::bind(isl::multi_id tuple) const
+isl::set pw_aff::ne_set(isl::pw_aff pwaff2) const
 {
-  if (!ptr || tuple.is_null())
+  if (!ptr || pwaff2.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_bind(copy(), tuple.release());
+  auto res = isl_pw_aff_ne_set(copy(), pwaff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff multi_pw_aff::bind_domain(isl::multi_id tuple) const
+isl::pw_aff pw_aff::neg() const
 {
-  if (!ptr || tuple.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_multi_pw_aff_bind_domain(copy(), tuple.release());
+  auto res = isl_pw_aff_neg(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff multi_pw_aff::bind_domain_wrapped_domain(isl::multi_id tuple) const
+isl::pw_aff pw_aff::param_on_domain(isl::set domain, isl::id id)
 {
-  if (!ptr || tuple.is_null())
+  if (domain.is_null() || id.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = domain.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_pw_aff_bind_domain_wrapped_domain(copy(), tuple.release());
+  auto res = isl_pw_aff_param_on_domain_id(domain.release(), id.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff multi_pw_aff::coalesce() const
+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())
+    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_coalesce(copy());
+  auto res = isl_pw_aff_pullback_multi_aff(copy(), ma.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set multi_pw_aff::domain() const
+isl::pw_aff pw_aff::pullback(isl::multi_pw_aff mpa) const
 {
-  if (!ptr)
+  if (!ptr || mpa.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_domain(copy());
+  auto res = isl_pw_aff_pullback_multi_pw_aff(copy(), mpa.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff multi_pw_aff::flat_range_product(isl::multi_pw_aff multi2) const
+isl::pw_aff pw_aff::pullback(isl::pw_multi_aff pma) const
 {
-  if (!ptr || multi2.is_null())
+  if (!ptr || pma.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_flat_range_product(copy(), multi2.release());
+  auto res = isl_pw_aff_pullback_pw_multi_aff(copy(), pma.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff multi_pw_aff::at(int pos) const
+isl::union_pw_aff pw_aff::pullback(const isl::union_pw_multi_aff &upma) 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::union_pw_aff(*this).pullback(upma);
 }
 
-isl::pw_aff multi_pw_aff::get_at(int pos) const
+isl::pw_multi_aff_list pw_aff::pw_multi_aff_list() const
 {
-  return at(pos);
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).pw_multi_aff_list();
 }
 
-isl::pw_aff_list multi_pw_aff::list() const
+isl::pw_multi_aff pw_aff::range_factor_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_multi_pw_aff_get_list(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_multi_aff(*this).range_factor_domain();
 }
 
-isl::pw_aff_list multi_pw_aff::get_list() const
+isl::pw_multi_aff pw_aff::range_factor_range() const
 {
-  return list();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).range_factor_range();
 }
 
-isl::space multi_pw_aff::space() const
+isl::multi_pw_aff pw_aff::range_product(const isl::multi_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_space(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_multi_aff(*this).range_product(multi2);
 }
 
-isl::space multi_pw_aff::get_space() const
+isl::multi_union_pw_aff pw_aff::range_product(const isl::multi_union_pw_aff &multi2) const
 {
-  return space();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).range_product(multi2);
 }
 
-isl::multi_pw_aff multi_pw_aff::gist(isl::set set) const
+isl::pw_multi_aff pw_aff::range_product(const isl::pw_multi_aff &pma2) const
 {
-  if (!ptr || set.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_multi_pw_aff_gist(copy(), set.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_multi_aff(*this).range_product(pma2);
 }
 
-isl::multi_pw_aff multi_pw_aff::identity() const
+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__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_pw_aff_identity_multi_pw_aff(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).range_product(upma2);
 }
 
-isl::multi_pw_aff multi_pw_aff::identity_on_domain(isl::space space)
+isl::id pw_aff::range_tuple_id() const
 {
-  if (space.is_null())
+  if (!ptr)
     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_pw_aff_identity_on_domain_space(space.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_multi_aff(*this).range_tuple_id();
 }
 
-isl::multi_pw_aff multi_pw_aff::insert_domain(isl::space domain) const
+isl::multi_pw_aff pw_aff::reset_range_tuple_id() const
 {
-  if (!ptr || domain.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_multi_pw_aff_insert_domain(copy(), domain.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_pw_aff(*this).reset_range_tuple_id();
 }
 
-isl::multi_pw_aff multi_pw_aff::intersect_domain(isl::set domain) const
+isl::multi_pw_aff pw_aff::scale(const isl::multi_val &mv) const
 {
-  if (!ptr || domain.is_null())
+  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())
     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_intersect_domain(copy(), domain.release());
+  auto res = isl_pw_aff_scale_val(copy(), v.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff multi_pw_aff::intersect_params(isl::set set) const
+isl::pw_aff pw_aff::scale(long v) const
 {
-  if (!ptr || set.is_null())
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  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())
     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_intersect_params(copy(), set.release());
+  auto res = isl_pw_aff_scale_down_val(copy(), f.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool multi_pw_aff::involves_nan() const
+isl::pw_aff pw_aff::scale_down(long f) 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_involves_nan(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return this->scale_down(isl::val(ctx(), f));
 }
 
-bool multi_pw_aff::involves_param(const isl::id &id) const
+isl::multi_pw_aff pw_aff::set_at(int pos, const isl::pw_aff &el) const
 {
-  if (!ptr || id.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_multi_pw_aff_involves_param_id(get(), id.get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::pw_multi_aff(*this).set_at(pos, el);
 }
 
-bool multi_pw_aff::involves_param(const std::string &id) const
+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 this->involves_param(isl::id(ctx(), id));
+  return isl::union_pw_aff(*this).set_at(pos, el);
 }
 
-bool multi_pw_aff::involves_param(const isl::id_list &list) const
+isl::pw_multi_aff pw_aff::set_range_tuple(const isl::id &id) const
 {
-  if (!ptr || list.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_multi_pw_aff_involves_param_id_list(get(), list.get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::pw_multi_aff(*this).set_range_tuple(id);
 }
 
-isl::multi_pw_aff multi_pw_aff::max(isl::multi_pw_aff multi2) const
+isl::pw_multi_aff pw_aff::set_range_tuple(const std::string &id) const
 {
-  if (!ptr || multi2.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_multi_pw_aff_max(copy(), multi2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->set_range_tuple(isl::id(ctx(), id));
 }
 
-isl::multi_val multi_pw_aff::max_multi_val() const
+unsigned pw_aff::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_multi_pw_aff_max_multi_val(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_pw_aff(*this).size();
 }
 
-isl::multi_pw_aff multi_pw_aff::min(isl::multi_pw_aff multi2) const
+isl::space pw_aff::space() const
 {
-  if (!ptr || multi2.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_multi_pw_aff_min(copy(), multi2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).space();
 }
 
-isl::multi_val multi_pw_aff::min_multi_val() const
+isl::multi_pw_aff pw_aff::sub(const isl::multi_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_min_multi_val(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_multi_aff(*this).sub(multi2);
 }
 
-isl::multi_pw_aff multi_pw_aff::neg() const
+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())
+    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_neg(copy());
+  auto res = isl_pw_aff_sub(copy(), pwaff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool multi_pw_aff::plain_is_equal(const isl::multi_pw_aff &multi2) const
+isl::pw_multi_aff pw_aff::sub(const isl::pw_multi_aff &pma2) const
 {
-  if (!ptr || multi2.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_multi_pw_aff_plain_is_equal(get(), multi2.get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::pw_multi_aff(*this).sub(pma2);
 }
 
-isl::multi_pw_aff multi_pw_aff::product(isl::multi_pw_aff multi2) const
+isl::union_pw_aff pw_aff::sub(const isl::union_pw_aff &upa2) const
 {
-  if (!ptr || multi2.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_multi_pw_aff_product(copy(), multi2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).sub(upa2);
 }
 
-isl::multi_pw_aff multi_pw_aff::pullback(isl::multi_aff ma) const
+isl::union_pw_multi_aff pw_aff::sub(const isl::union_pw_multi_aff &upma2) const
 {
-  if (!ptr || ma.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_multi_pw_aff_pullback_multi_aff(copy(), ma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).sub(upma2);
 }
 
-isl::multi_pw_aff multi_pw_aff::pullback(isl::multi_pw_aff mpa2) const
+isl::pw_aff pw_aff::sub(const isl::aff &pwaff2) const
 {
-  if (!ptr || mpa2.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_multi_pw_aff_pullback_multi_pw_aff(copy(), mpa2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->sub(isl::pw_aff(pwaff2));
 }
 
-isl::multi_pw_aff multi_pw_aff::pullback(isl::pw_multi_aff pma) const
+isl::pw_aff pw_aff::subtract_domain(isl::set set) const
 {
-  if (!ptr || pma.is_null())
+  if (!ptr || set.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_pullback_pw_multi_aff(copy(), pma.release());
+  auto res = isl_pw_aff_subtract_domain(copy(), set.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff multi_pw_aff::range_product(isl::multi_pw_aff multi2) const
+isl::union_pw_aff pw_aff::subtract_domain(const isl::space &space) const
 {
-  if (!ptr || multi2.is_null())
+  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())
     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_range_product(copy(), multi2.release());
+  auto res = isl_pw_aff_tdiv_q(copy(), pa2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff multi_pw_aff::scale(isl::multi_val mv) const
+isl::pw_aff pw_aff::tdiv_r(isl::pw_aff pa2) const
 {
-  if (!ptr || mv.is_null())
+  if (!ptr || pa2.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_scale_multi_val(copy(), mv.release());
+  auto res = isl_pw_aff_tdiv_r(copy(), pa2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff multi_pw_aff::scale(isl::val v) const
+isl::pw_aff_list pw_aff::to_list() const
 {
-  if (!ptr || v.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_multi_pw_aff_scale_val(copy(), v.release());
+  auto res = isl_pw_aff_to_list(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff multi_pw_aff::scale(long v) const
+isl::multi_pw_aff pw_aff::to_multi_pw_aff() const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->scale(isl::val(ctx(), v));
+  return isl::pw_multi_aff(*this).to_multi_pw_aff();
 }
 
-isl::multi_pw_aff multi_pw_aff::scale_down(isl::multi_val mv) const
+isl::union_pw_aff pw_aff::to_union_pw_aff() const
 {
-  if (!ptr || mv.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_multi_pw_aff_scale_down_multi_val(copy(), mv.release());
+  auto res = isl_pw_aff_to_union_pw_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff multi_pw_aff::scale_down(isl::val v) const
+isl::union_pw_multi_aff pw_aff::to_union_pw_multi_aff() const
 {
-  if (!ptr || v.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_multi_pw_aff_scale_down_val(copy(), v.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_multi_aff(*this).to_union_pw_multi_aff();
 }
 
-isl::multi_pw_aff multi_pw_aff::scale_down(long v) const
+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 this->scale_down(isl::val(ctx(), v));
+  return isl::pw_multi_aff(*this).unbind_params_insert_domain(domain);
 }
 
-isl::multi_pw_aff multi_pw_aff::set_at(int pos, isl::pw_aff el) const
+isl::multi_pw_aff pw_aff::union_add(const isl::multi_pw_aff &mpa2) const
 {
-  if (!ptr || el.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_multi_pw_aff_set_at(copy(), pos, el.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_multi_aff(*this).union_add(mpa2);
 }
 
-unsigned multi_pw_aff::size() const
+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__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_pw_aff_size(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::union_pw_aff(*this).union_add(mupa2);
 }
 
-isl::multi_pw_aff multi_pw_aff::sub(isl::multi_pw_aff multi2) const
+isl::pw_aff pw_aff::union_add(isl::pw_aff pwaff2) const
 {
-  if (!ptr || multi2.is_null())
+  if (!ptr || pwaff2.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_sub(copy(), multi2.release());
+  auto res = isl_pw_aff_union_add(copy(), pwaff2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff multi_pw_aff::unbind_params_insert_domain(isl::multi_id domain) const
+isl::pw_multi_aff pw_aff::union_add(const isl::pw_multi_aff &pma2) const
 {
-  if (!ptr || domain.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_multi_pw_aff_unbind_params_insert_domain(copy(), domain.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_multi_aff(*this).union_add(pma2);
 }
 
-isl::multi_pw_aff multi_pw_aff::union_add(isl::multi_pw_aff mpa2) const
+isl::union_pw_aff pw_aff::union_add(const isl::union_pw_aff &upa2) const
 {
-  if (!ptr || mpa2.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_multi_pw_aff_union_add(copy(), mpa2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).union_add(upa2);
 }
 
-isl::multi_pw_aff multi_pw_aff::zero(isl::space space)
+isl::union_pw_multi_aff pw_aff::union_add(const isl::union_pw_multi_aff &upma2) const
 {
-  if (space.is_null())
+  if (!ptr)
     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_pw_aff_zero(space.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_aff(*this).union_add(upma2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const multi_pw_aff &obj)
+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())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_pw_aff_get_ctx(obj.get());
+  auto saved_ctx = isl_pw_aff_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_multi_pw_aff_to_str(obj.get());
+  char *str = isl_pw_aff_to_str(obj.get());
   if (!str)
     exception::throw_last_error(saved_ctx);
   os << str;
@@ -9842,1569 +18088,1696 @@ inline std::ostream &operator<<(std::ostream &os, const multi_pw_aff &obj)
   return os;
 }
 
-// implementations for isl::multi_union_pw_aff
-multi_union_pw_aff manage(__isl_take isl_multi_union_pw_aff *ptr) {
+// implementations for isl::pw_aff_list
+pw_aff_list manage(__isl_take isl_pw_aff_list *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return multi_union_pw_aff(ptr);
+  return pw_aff_list(ptr);
 }
-multi_union_pw_aff manage_copy(__isl_keep isl_multi_union_pw_aff *ptr) {
+pw_aff_list manage_copy(__isl_keep isl_pw_aff_list *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_union_pw_aff_get_ctx(ptr);
+  auto saved_ctx = isl_pw_aff_list_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_multi_union_pw_aff_copy(ptr);
+  ptr = isl_pw_aff_list_copy(ptr);
   if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return multi_union_pw_aff(ptr);
+  return pw_aff_list(ptr);
 }
 
-multi_union_pw_aff::multi_union_pw_aff()
+pw_aff_list::pw_aff_list()
     : ptr(nullptr) {}
 
-multi_union_pw_aff::multi_union_pw_aff(const multi_union_pw_aff &obj)
+pw_aff_list::pw_aff_list(const pw_aff_list &obj)
     : ptr(nullptr)
 {
   if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_union_pw_aff_get_ctx(obj.ptr);
+  auto saved_ctx = isl_pw_aff_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);
 }
 
-multi_union_pw_aff::multi_union_pw_aff(__isl_take isl_multi_union_pw_aff *ptr)
+pw_aff_list::pw_aff_list(__isl_take isl_pw_aff_list *ptr)
     : ptr(ptr) {}
 
-multi_union_pw_aff::multi_union_pw_aff(isl::multi_pw_aff mpa)
-{
-  if (mpa.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = mpa.ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_union_pw_aff_from_multi_pw_aff(mpa.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-multi_union_pw_aff::multi_union_pw_aff(isl::union_pw_aff upa)
+pw_aff_list::pw_aff_list(isl::ctx ctx, int n)
 {
-  if (upa.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = upa.ctx();
+  auto saved_ctx = ctx;
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_union_pw_aff_from_union_pw_aff(upa.release());
+  auto res = isl_pw_aff_list_alloc(ctx.release(), n);
   if (!res)
     exception::throw_last_error(saved_ctx);
   ptr = res;
 }
 
-multi_union_pw_aff::multi_union_pw_aff(isl::space space, isl::union_pw_aff_list list)
+pw_aff_list::pw_aff_list(isl::pw_aff el)
 {
-  if (space.is_null() || list.is_null())
+  if (el.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
+  auto saved_ctx = el.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_union_pw_aff_from_union_pw_aff_list(space.release(), list.release());
+  auto res = isl_pw_aff_list_from_pw_aff(el.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   ptr = res;
 }
 
-multi_union_pw_aff::multi_union_pw_aff(isl::ctx ctx, const std::string &str)
+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_multi_union_pw_aff_read_from_str(ctx.release(), str.c_str());
+  auto res = isl_pw_aff_list_read_from_str(ctx.release(), str.c_str());
   if (!res)
     exception::throw_last_error(saved_ctx);
   ptr = res;
 }
 
-multi_union_pw_aff &multi_union_pw_aff::operator=(multi_union_pw_aff obj) {
+pw_aff_list &pw_aff_list::operator=(pw_aff_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-multi_union_pw_aff::~multi_union_pw_aff() {
+pw_aff_list::~pw_aff_list() {
   if (ptr)
-    isl_multi_union_pw_aff_free(ptr);
+    isl_pw_aff_list_free(ptr);
 }
 
-__isl_give isl_multi_union_pw_aff *multi_union_pw_aff::copy() const & {
-  return isl_multi_union_pw_aff_copy(ptr);
+__isl_give isl_pw_aff_list *pw_aff_list::copy() const & {
+  return isl_pw_aff_list_copy(ptr);
 }
 
-__isl_keep isl_multi_union_pw_aff *multi_union_pw_aff::get() const {
+__isl_keep isl_pw_aff_list *pw_aff_list::get() const {
   return ptr;
 }
 
-__isl_give isl_multi_union_pw_aff *multi_union_pw_aff::release() {
-  isl_multi_union_pw_aff *tmp = ptr;
+__isl_give isl_pw_aff_list *pw_aff_list::release() {
+  isl_pw_aff_list *tmp = ptr;
   ptr = nullptr;
   return tmp;
 }
 
-bool multi_union_pw_aff::is_null() const {
+bool pw_aff_list::is_null() const {
   return ptr == nullptr;
 }
 
-isl::ctx multi_union_pw_aff::ctx() const {
-  return isl::ctx(isl_multi_union_pw_aff_get_ctx(ptr));
-}
-
-isl::multi_union_pw_aff multi_union_pw_aff::add(isl::multi_union_pw_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_union_pw_aff_add(copy(), multi2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::union_set multi_union_pw_aff::bind(isl::multi_id tuple) const
-{
-  if (!ptr || tuple.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_bind(copy(), tuple.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::multi_union_pw_aff multi_union_pw_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_union_pw_aff_coalesce(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::union_set multi_union_pw_aff::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_multi_union_pw_aff_domain(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::multi_union_pw_aff multi_union_pw_aff::flat_range_product(isl::multi_union_pw_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_union_pw_aff_flat_range_product(copy(), multi2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+isl::ctx pw_aff_list::ctx() const {
+  return isl::ctx(isl_pw_aff_list_get_ctx(ptr));
 }
 
-isl::union_pw_aff multi_union_pw_aff::at(int pos) const
+isl::pw_aff_list pw_aff_list::add(isl::pw_aff el) const
 {
-  if (!ptr)
+  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_multi_union_pw_aff_get_at(get(), pos);
+  auto res = isl_pw_aff_list_add(copy(), el.release());
   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
+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_multi_union_pw_aff_get_list(get());
+  auto res = isl_pw_aff_list_get_at(get(), index);
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_pw_aff_list multi_union_pw_aff::get_list() const
+isl::pw_aff pw_aff_list::get_at(int index) const
 {
-  return list();
+  return at(index);
 }
 
-isl::space multi_union_pw_aff::space() const
+isl::pw_aff_list pw_aff_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_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())
-    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_gist(copy(), context.release());
+  auto res = isl_pw_aff_list_clear(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::intersect_domain(isl::union_set uset) const
+isl::pw_aff_list pw_aff_list::concat(isl::pw_aff_list list2) const
 {
-  if (!ptr || uset.is_null())
+  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_multi_union_pw_aff_intersect_domain(copy(), uset.release());
+  auto res = isl_pw_aff_list_concat(copy(), list2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::intersect_params(isl::set params) const
+isl::pw_aff_list pw_aff_list::drop(unsigned int first, unsigned int n) const
 {
-  if (!ptr || params.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_multi_union_pw_aff_intersect_params(copy(), params.release());
+  auto res = isl_pw_aff_list_drop(copy(), first, n);
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool multi_union_pw_aff::involves_nan() const
+void pw_aff_list::foreach(const std::function<void(isl::pw_aff)> &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_multi_union_pw_aff_involves_nan(get());
+  struct fn_data {
+    std::function<void(isl::pw_aff)> func;
+    std::exception_ptr eptr;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_pw_aff *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_pw_aff_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 res;
+  return;
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::neg() const
+isl::pw_aff_list pw_aff_list::insert(unsigned int pos, isl::pw_aff el) const
 {
-  if (!ptr)
+  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_multi_union_pw_aff_neg(copy());
+  auto res = isl_pw_aff_list_insert(copy(), pos, el.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool multi_union_pw_aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const
+unsigned pw_aff_list::size() const
 {
-  if (!ptr || multi2.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_multi_union_pw_aff_plain_is_equal(get(), multi2.get());
+  auto res = isl_pw_aff_list_size(get());
   if (res < 0)
     exception::throw_last_error(saved_ctx);
   return res;
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::pullback(isl::union_pw_multi_aff upma) const
+inline std::ostream &operator<<(std::ostream &os, const pw_aff_list &obj)
 {
-  if (!ptr || upma.is_null())
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_pw_aff_list_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_union_pw_aff_pullback_union_pw_multi_aff(copy(), upma.release());
-  if (!res)
+  char *str = isl_pw_aff_list_to_str(obj.get());
+  if (!str)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  os << str;
+  free(str);
+  return os;
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::range_product(isl::multi_union_pw_aff multi2) const
-{
-  if (!ptr || multi2.is_null())
+// implementations for isl::pw_multi_aff
+pw_multi_aff manage(__isl_take isl_pw_multi_aff *ptr) {
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  return pw_multi_aff(ptr);
+}
+pw_multi_aff manage_copy(__isl_keep isl_pw_multi_aff *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_pw_multi_aff_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_union_pw_aff_range_product(copy(), multi2.release());
-  if (!res)
+  ptr = isl_pw_multi_aff_copy(ptr);
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return pw_multi_aff(ptr);
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::scale(isl::multi_val mv) const
+pw_multi_aff::pw_multi_aff()
+    : ptr(nullptr) {}
+
+pw_multi_aff::pw_multi_aff(const pw_multi_aff &obj)
+    : ptr(nullptr)
 {
-  if (!ptr || mv.is_null())
+  if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_pw_multi_aff_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_union_pw_aff_scale_multi_val(copy(), mv.release());
-  if (!res)
+  ptr = obj.copy();
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::scale(isl::val v) const
+pw_multi_aff::pw_multi_aff(__isl_take isl_pw_multi_aff *ptr)
+    : ptr(ptr) {}
+
+pw_multi_aff::pw_multi_aff(isl::multi_aff ma)
 {
-  if (!ptr || v.is_null())
+  if (ma.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = ma.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_union_pw_aff_scale_val(copy(), v.release());
+  auto res = isl_pw_multi_aff_from_multi_aff(ma.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  ptr = res;
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::scale(long v) const
+pw_multi_aff::pw_multi_aff(isl::pw_aff pa)
 {
-  if (!ptr)
+  if (pa.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->scale(isl::val(ctx(), v));
+  auto saved_ctx = pa.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_from_pw_aff(pa.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::scale_down(isl::multi_val mv) const
+pw_multi_aff::pw_multi_aff(isl::ctx ctx, const std::string &str)
 {
-  if (!ptr || mv.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = ctx;
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_union_pw_aff_scale_down_multi_val(copy(), mv.release());
+  auto res = isl_pw_multi_aff_read_from_str(ctx.release(), str.c_str());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  ptr = res;
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::scale_down(isl::val v) const
+pw_multi_aff &pw_multi_aff::operator=(pw_multi_aff obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+pw_multi_aff::~pw_multi_aff() {
+  if (ptr)
+    isl_pw_multi_aff_free(ptr);
+}
+
+__isl_give isl_pw_multi_aff *pw_multi_aff::copy() const & {
+  return isl_pw_multi_aff_copy(ptr);
+}
+
+__isl_keep isl_pw_multi_aff *pw_multi_aff::get() const {
+  return ptr;
+}
+
+__isl_give isl_pw_multi_aff *pw_multi_aff::release() {
+  isl_pw_multi_aff *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool pw_multi_aff::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx pw_multi_aff::ctx() const {
+  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 || v.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_multi_union_pw_aff_scale_down_val(copy(), v.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_pw_aff(*this).add(multi2);
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::scale_down(long v) const
+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 this->scale_down(isl::val(ctx(), v));
+  return isl::multi_pw_aff(*this).add(multi2);
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::set_at(int pos, isl::union_pw_aff el) const
+isl::pw_multi_aff pw_multi_aff::add(isl::pw_multi_aff pma2) const
 {
-  if (!ptr || el.is_null())
+  if (!ptr || pma2.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_at(copy(), pos, el.release());
+  auto res = isl_pw_multi_aff_add(copy(), pma2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-unsigned multi_union_pw_aff::size() const
+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__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_union_pw_aff_size(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::union_pw_multi_aff(*this).add(upma2);
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::sub(isl::multi_union_pw_aff multi2) const
+isl::pw_multi_aff pw_multi_aff::add(const isl::multi_aff &pma2) const
 {
-  if (!ptr || multi2.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_multi_union_pw_aff_sub(copy(), multi2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->add(isl::pw_multi_aff(pma2));
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::union_add(isl::multi_union_pw_aff mupa2) const
+isl::pw_multi_aff pw_multi_aff::add(const isl::pw_aff &pma2) const
 {
-  if (!ptr || mupa2.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_multi_union_pw_aff_union_add(copy(), mupa2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->add(isl::pw_multi_aff(pma2));
 }
 
-isl::multi_union_pw_aff multi_union_pw_aff::zero(isl::space space)
+isl::pw_multi_aff pw_multi_aff::add_constant(isl::multi_val mv) const
 {
-  if (space.is_null())
+  if (!ptr || mv.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_union_pw_aff_zero(space.release());
+  auto res = isl_pw_multi_aff_add_constant_multi_val(copy(), mv.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const multi_union_pw_aff &obj)
+isl::pw_multi_aff pw_multi_aff::add_constant(isl::val v) const
 {
-  if (!obj.get())
+  if (!ptr || v.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_union_pw_aff_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_multi_union_pw_aff_to_str(obj.get());
-  if (!str)
+  auto res = isl_pw_multi_aff_add_constant_val(copy(), v.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::multi_val
-multi_val manage(__isl_take isl_multi_val *ptr) {
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return multi_val(ptr);
-}
-multi_val manage_copy(__isl_keep isl_multi_val *ptr) {
+isl::pw_multi_aff pw_multi_aff::add_constant(long v) const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_val_get_ctx(ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_multi_val_copy(ptr);
-  if (!ptr)
-    exception::throw_last_error(saved_ctx);
-  return multi_val(ptr);
+  return this->add_constant(isl::val(ctx(), v));
 }
 
-multi_val::multi_val()
-    : ptr(nullptr) {}
-
-multi_val::multi_val(const multi_val &obj)
-    : ptr(nullptr)
+isl::union_pw_multi_aff pw_multi_aff::apply(const isl::union_pw_multi_aff &upma2) const
 {
-  if (!obj.ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_val_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);
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).apply(upma2);
 }
 
-multi_val::multi_val(__isl_take isl_multi_val *ptr)
-    : ptr(ptr) {}
-
-multi_val::multi_val(isl::space space, isl::val_list list)
+isl::map pw_multi_aff::as_map() const
 {
-  if (space.is_null() || list.is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_val_from_val_list(space.release(), list.release());
+  auto res = isl_pw_multi_aff_as_map(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-multi_val::multi_val(isl::ctx ctx, const std::string &str)
+isl::multi_aff pw_multi_aff::as_multi_aff() const
 {
-  auto saved_ctx = ctx;
+  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_read_from_str(ctx.release(), str.c_str());
+  auto res = isl_pw_multi_aff_as_multi_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-multi_val &multi_val::operator=(multi_val obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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();
 }
 
-multi_val::~multi_val() {
-  if (ptr)
-    isl_multi_val_free(ptr);
+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_give isl_multi_val *multi_val::copy() const & {
-  return isl_multi_val_copy(ptr);
+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_keep isl_multi_val *multi_val::get() const {
-  return ptr;
+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_give isl_multi_val *multi_val::release() {
-  isl_multi_val *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+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);
 }
 
-bool multi_val::is_null() const {
-  return ptr == nullptr;
+isl::pw_aff pw_multi_aff::get_at(int pos) const
+{
+  return at(pos);
 }
 
-isl::ctx multi_val::ctx() const {
-  return isl::ctx(isl_multi_val_get_ctx(ptr));
+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::multi_val multi_val::add(isl::multi_val multi2) const
+isl::pw_multi_aff pw_multi_aff::bind_domain(isl::multi_id tuple) const
 {
-  if (!ptr || multi2.is_null())
+  if (!ptr || tuple.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_add(copy(), multi2.release());
+  auto res = isl_pw_multi_aff_bind_domain(copy(), tuple.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_val multi_val::add(isl::val v) const
+isl::pw_multi_aff pw_multi_aff::bind_domain_wrapped_domain(isl::multi_id tuple) const
 {
-  if (!ptr || v.is_null())
+  if (!ptr || tuple.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_add_val(copy(), v.release());
+  auto res = isl_pw_multi_aff_bind_domain_wrapped_domain(copy(), tuple.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_val multi_val::add(long v) const
+isl::pw_multi_aff pw_multi_aff::coalesce() const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->add(isl::val(ctx(), v));
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_coalesce(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::multi_val multi_val::flat_range_product(isl::multi_val multi2) const
+isl::set pw_multi_aff::domain() const
 {
-  if (!ptr || multi2.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_multi_val_flat_range_product(copy(), multi2.release());
+  auto res = isl_pw_multi_aff_domain(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::val multi_val::at(int pos) const
+isl::pw_multi_aff pw_multi_aff::domain_map(isl::space space)
 {
-  if (!ptr)
+  if (space.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = space.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_val_get_at(get(), pos);
+  auto res = isl_pw_multi_aff_domain_map(space.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::val multi_val::get_at(int pos) const
+isl::pw_multi_aff pw_multi_aff::extract_pw_multi_aff(const isl::space &space) const
 {
-  return at(pos);
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).extract_pw_multi_aff(space);
 }
 
-isl::val_list multi_val::list() const
+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())
+    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_list(get());
+  auto res = isl_pw_multi_aff_flat_range_product(copy(), pma2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::val_list multi_val::get_list() const
+isl::union_pw_multi_aff pw_multi_aff::flat_range_product(const isl::union_pw_multi_aff &upma2) const
 {
-  return list();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).flat_range_product(upma2);
 }
 
-isl::space multi_val::space() const
+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__);
-  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);
+  return this->flat_range_product(isl::pw_multi_aff(pma2));
 }
 
-isl::space multi_val::get_space() const
+isl::pw_multi_aff pw_multi_aff::flat_range_product(const isl::pw_aff &pma2) const
 {
-  return space();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->flat_range_product(isl::pw_multi_aff(pma2));
 }
 
-bool multi_val::involves_nan() const
+void pw_multi_aff::foreach_piece(const std::function<void(isl::set, isl::multi_aff)> &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_multi_val_involves_nan(get());
+  struct fn_data {
+    std::function<void(isl::set, isl::multi_aff)> func;
+    std::exception_ptr eptr;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_set *arg_0, isl_multi_aff *arg_1, void *arg_2) -> isl_stat {
+    auto *data = static_cast<struct fn_data *>(arg_2);
+    ISL_CPP_TRY {
+      (data->func)(manage(arg_0), manage(arg_1));
+      return isl_stat_ok;
+    } ISL_CPP_CATCH_ALL {
+      data->eptr = std::current_exception();
+      return isl_stat_error;
+    }
+  };
+  auto res = isl_pw_multi_aff_foreach_piece(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 res;
+  return;
 }
 
-isl::multi_val multi_val::max(isl::multi_val multi2) const
+isl::pw_multi_aff pw_multi_aff::gist(isl::set set) const
 {
-  if (!ptr || multi2.is_null())
+  if (!ptr || set.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_max(copy(), multi2.release());
+  auto res = isl_pw_multi_aff_gist(copy(), set.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_val multi_val::min(isl::multi_val multi2) const
+isl::union_pw_multi_aff pw_multi_aff::gist(const isl::union_set &context) const
 {
-  if (!ptr || multi2.is_null())
+  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_multi_val_min(copy(), multi2.release());
-  if (!res)
+  auto res = isl_pw_multi_aff_has_range_tuple_id(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::multi_val multi_val::neg() const
+isl::multi_pw_aff pw_multi_aff::identity() const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  return isl::multi_pw_aff(*this).identity();
+}
+
+isl::pw_multi_aff pw_multi_aff::identity_on_domain(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_val_neg(copy());
+  auto res = isl_pw_multi_aff_identity_on_domain_space(space.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool multi_val::plain_is_equal(const isl::multi_val &multi2) const
+isl::pw_multi_aff pw_multi_aff::insert_domain(isl::space domain) const
 {
-  if (!ptr || multi2.is_null())
+  if (!ptr || domain.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_plain_is_equal(get(), multi2.get());
-  if (res < 0)
+  auto res = isl_pw_multi_aff_insert_domain(copy(), domain.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-isl::multi_val multi_val::product(isl::multi_val multi2) const
+isl::pw_multi_aff pw_multi_aff::intersect_domain(isl::set set) const
 {
-  if (!ptr || multi2.is_null())
+  if (!ptr || set.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_product(copy(), multi2.release());
+  auto res = isl_pw_multi_aff_intersect_domain(copy(), set.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_val multi_val::range_product(isl::multi_val multi2) const
+isl::union_pw_multi_aff pw_multi_aff::intersect_domain(const isl::space &space) const
 {
-  if (!ptr || multi2.is_null())
+  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())
     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_range_product(copy(), multi2.release());
+  auto res = isl_pw_multi_aff_intersect_params(copy(), set.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_val multi_val::scale(isl::multi_val mv) const
+bool pw_multi_aff::involves_locals() const
 {
-  if (!ptr || mv.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_multi_val_scale_multi_val(copy(), mv.release());
-  if (!res)
+  auto res = isl_pw_multi_aff_involves_locals(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  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();
 }
 
-isl::multi_val multi_val::scale(isl::val v) const
+bool pw_multi_aff::involves_param(const isl::id &id) const
 {
-  if (!ptr || v.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_multi_val_scale_val(copy(), v.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_pw_aff(*this).involves_param(id);
 }
 
-isl::multi_val multi_val::scale(long v) const
+bool pw_multi_aff::involves_param(const std::string &id) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->scale(isl::val(ctx(), v));
+  return this->involves_param(isl::id(ctx(), id));
 }
 
-isl::multi_val multi_val::scale_down(isl::multi_val mv) const
+bool pw_multi_aff::involves_param(const isl::id_list &list) const
 {
-  if (!ptr || mv.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_multi_val_scale_down_multi_val(copy(), mv.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_pw_aff(*this).involves_param(list);
 }
 
-isl::multi_val multi_val::scale_down(isl::val v) const
+bool pw_multi_aff::isa_multi_aff() const
 {
-  if (!ptr || v.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_multi_val_scale_down_val(copy(), v.release());
-  if (!res)
+  auto res = isl_pw_multi_aff_isa_multi_aff(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::multi_val multi_val::scale_down(long v) const
+bool pw_multi_aff::isa_pw_multi_aff() const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->scale_down(isl::val(ctx(), v));
+  return isl::union_pw_multi_aff(*this).isa_pw_multi_aff();
 }
 
-isl::multi_val multi_val::set_at(int pos, isl::val el) const
+isl::pw_aff_list pw_multi_aff::list() const
 {
-  if (!ptr || el.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_multi_val_set_at(copy(), pos, el.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_pw_aff(*this).list();
 }
 
-isl::multi_val multi_val::set_at(int pos, long el) const
+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 this->set_at(pos, isl::val(ctx(), el));
+  return isl::multi_pw_aff(*this).max(multi2);
 }
 
-unsigned multi_val::size() const
+isl::multi_val pw_multi_aff::max_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_multi_val_size(get());
-  if (res < 0)
+  auto res = isl_pw_multi_aff_max_multi_val(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-isl::multi_val multi_val::sub(isl::multi_val multi2) const
+isl::multi_pw_aff pw_multi_aff::min(const isl::multi_pw_aff &multi2) const
 {
-  if (!ptr || multi2.is_null())
+  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)
     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_sub(copy(), multi2.release());
+  auto res = isl_pw_multi_aff_min_multi_val(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_val multi_val::zero(isl::space space)
+isl::pw_multi_aff pw_multi_aff::multi_val_on_domain(isl::set domain, isl::multi_val mv)
 {
-  if (space.is_null())
+  if (domain.is_null() || mv.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
+  auto saved_ctx = domain.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_val_zero(space.release());
+  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);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const multi_val &obj)
+unsigned pw_multi_aff::n_piece() const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_multi_val_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_multi_val_to_str(obj.get());
-  if (!str)
+  auto res = isl_pw_multi_aff_n_piece(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return res;
 }
 
-// implementations for isl::point
-point manage(__isl_take isl_point *ptr) {
+isl::multi_pw_aff pw_multi_aff::neg() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return point(ptr);
+  return isl::multi_pw_aff(*this).neg();
 }
-point manage_copy(__isl_keep isl_point *ptr) {
+
+bool pw_multi_aff::plain_is_empty() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_point_get_ctx(ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_point_copy(ptr);
-  if (!ptr)
-    exception::throw_last_error(saved_ctx);
-  return point(ptr);
+  return isl::union_pw_multi_aff(*this).plain_is_empty();
 }
 
-point::point()
-    : ptr(nullptr) {}
-
-point::point(const point &obj)
-    : ptr(nullptr)
+bool pw_multi_aff::plain_is_equal(const isl::multi_pw_aff &multi2) const
 {
-  if (!obj.ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_point_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);
-}
-
-point::point(__isl_take isl_point *ptr)
-    : ptr(ptr) {}
-
-point &point::operator=(point obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-point::~point() {
-  if (ptr)
-    isl_point_free(ptr);
-}
-
-__isl_give isl_point *point::copy() const & {
-  return isl_point_copy(ptr);
-}
-
-__isl_keep isl_point *point::get() const {
-  return ptr;
-}
-
-__isl_give isl_point *point::release() {
-  isl_point *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
-}
-
-bool point::is_null() const {
-  return ptr == nullptr;
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).plain_is_equal(multi2);
 }
 
-isl::ctx point::ctx() const {
-  return isl::ctx(isl_point_get_ctx(ptr));
+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::multi_val point::multi_val() const
+isl::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(isl::pw_multi_aff pma2) const
 {
-  if (!ptr)
+  if (!ptr || pma2.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_point_get_multi_val(get());
+  auto res = isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(copy(), pma2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_val point::get_multi_val() const
+isl::union_pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const
 {
-  return multi_val();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).preimage_domain_wrapped_domain(upma2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const point &obj)
+isl::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::multi_aff &pma2) const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_point_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_point_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return this->preimage_domain_wrapped_domain(isl::pw_multi_aff(pma2));
 }
 
-// implementations for isl::pw_aff
-pw_aff manage(__isl_take isl_pw_aff *ptr) {
+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 pw_aff(ptr);
+  return this->preimage_domain_wrapped_domain(isl::pw_multi_aff(pma2));
 }
-pw_aff manage_copy(__isl_keep isl_pw_aff *ptr) {
+
+isl::multi_pw_aff pw_multi_aff::product(const isl::multi_pw_aff &multi2) const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_pw_aff_get_ctx(ptr);
+  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())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_pw_aff_copy(ptr);
-  if (!ptr)
+  auto res = isl_pw_multi_aff_product(copy(), pma2.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return pw_aff(ptr);
+  return manage(res);
 }
 
-pw_aff::pw_aff()
-    : ptr(nullptr) {}
-
-pw_aff::pw_aff(const pw_aff &obj)
-    : ptr(nullptr)
+isl::pw_multi_aff pw_multi_aff::product(const isl::multi_aff &pma2) const
 {
-  if (!obj.ptr)
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_pw_aff_get_ctx(obj.ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = obj.copy();
+  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_last_error(saved_ctx);
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->product(isl::pw_multi_aff(pma2));
 }
 
-pw_aff::pw_aff(__isl_take isl_pw_aff *ptr)
-    : ptr(ptr) {}
+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);
+}
 
-pw_aff::pw_aff(isl::aff aff)
+isl::pw_multi_aff pw_multi_aff::pullback(isl::multi_aff ma) const
 {
-  if (aff.is_null())
+  if (!ptr || ma.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = aff.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_aff_from_aff(aff.release());
+  auto res = isl_pw_multi_aff_pullback_multi_aff(copy(), ma.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-pw_aff::pw_aff(isl::ctx ctx, const std::string &str)
+isl::pw_multi_aff pw_multi_aff::pullback(isl::pw_multi_aff pma2) const
 {
-  auto saved_ctx = ctx;
+  if (!ptr || pma2.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_aff_read_from_str(ctx.release(), str.c_str());
+  auto res = isl_pw_multi_aff_pullback_pw_multi_aff(copy(), pma2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-pw_aff &pw_aff::operator=(pw_aff obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-pw_aff::~pw_aff() {
-  if (ptr)
-    isl_pw_aff_free(ptr);
-}
-
-__isl_give isl_pw_aff *pw_aff::copy() const & {
-  return isl_pw_aff_copy(ptr);
-}
-
-__isl_keep isl_pw_aff *pw_aff::get() const {
-  return ptr;
-}
-
-__isl_give isl_pw_aff *pw_aff::release() {
-  isl_pw_aff *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+  return manage(res);
 }
 
-bool pw_aff::is_null() const {
-  return ptr == nullptr;
+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::ctx pw_aff::ctx() const {
-  return isl::ctx(isl_pw_aff_get_ctx(ptr));
+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_aff pw_aff::add(isl::pw_aff pwaff2) const
+isl::pw_multi_aff pw_multi_aff::range_factor_domain() const
 {
-  if (!ptr || pwaff2.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_pw_aff_add(copy(), pwaff2.release());
+  auto res = isl_pw_multi_aff_range_factor_domain(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::add_constant(isl::val v) const
+isl::pw_multi_aff pw_multi_aff::range_factor_range() const
 {
-  if (!ptr || v.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_pw_aff_add_constant_val(copy(), v.release());
+  auto res = isl_pw_multi_aff_range_factor_range(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::add_constant(long v) const
+isl::pw_multi_aff pw_multi_aff::range_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_pw_multi_aff_range_map(space.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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 this->add_constant(isl::val(ctx(), v));
+  return isl::multi_pw_aff(*this).range_product(multi2);
 }
 
-isl::aff pw_aff::as_aff() const
+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__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_aff_as_aff(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_pw_aff(*this).range_product(multi2);
 }
 
-isl::set pw_aff::bind(isl::id id) const
+isl::pw_multi_aff pw_multi_aff::range_product(isl::pw_multi_aff pma2) const
 {
-  if (!ptr || id.is_null())
+  if (!ptr || pma2.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_aff_bind_id(copy(), id.release());
+  auto res = isl_pw_multi_aff_range_product(copy(), pma2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set pw_aff::bind(const std::string &id) const
+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 this->bind(isl::id(ctx(), id));
+  return isl::union_pw_multi_aff(*this).range_product(upma2);
 }
 
-isl::pw_aff pw_aff::bind_domain(isl::multi_id tuple) const
+isl::pw_multi_aff pw_multi_aff::range_product(const isl::multi_aff &pma2) const
 {
-  if (!ptr || tuple.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_pw_aff_bind_domain(copy(), tuple.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->range_product(isl::pw_multi_aff(pma2));
 }
 
-isl::pw_aff pw_aff::bind_domain_wrapped_domain(isl::multi_id tuple) const
+isl::pw_multi_aff pw_multi_aff::range_product(const isl::pw_aff &pma2) const
 {
-  if (!ptr || tuple.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_pw_aff_bind_domain_wrapped_domain(copy(), tuple.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->range_product(isl::pw_multi_aff(pma2));
 }
 
-isl::pw_aff pw_aff::ceil() const
+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_aff_ceil(copy());
+  auto res = isl_pw_multi_aff_get_range_tuple_id(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::coalesce() const
+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__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_aff_coalesce(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_pw_aff(*this).reset_range_tuple_id();
 }
 
-isl::pw_aff pw_aff::cond(isl::pw_aff pwaff_true, isl::pw_aff pwaff_false) const
+isl::multi_pw_aff pw_multi_aff::scale(const isl::multi_val &mv) const
 {
-  if (!ptr || pwaff_true.is_null() || pwaff_false.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_pw_aff_cond(copy(), pwaff_true.release(), pwaff_false.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_pw_aff(*this).scale(mv);
 }
 
-isl::pw_aff pw_aff::div(isl::pw_aff pa2) const
+isl::pw_multi_aff pw_multi_aff::scale(isl::val v) const
 {
-  if (!ptr || pa2.is_null())
+  if (!ptr || v.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_aff_div(copy(), pa2.release());
+  auto res = isl_pw_multi_aff_scale_val(copy(), v.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set pw_aff::domain() const
+isl::pw_multi_aff pw_multi_aff::scale(long v) 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_domain(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->scale(isl::val(ctx(), v));
 }
 
-isl::set pw_aff::eq_set(isl::pw_aff pwaff2) const
+isl::multi_pw_aff pw_multi_aff::scale_down(const isl::multi_val &mv) const
 {
-  if (!ptr || pwaff2.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_pw_aff_eq_set(copy(), pwaff2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_pw_aff(*this).scale_down(mv);
 }
 
-isl::val pw_aff::eval(isl::point pnt) const
+isl::pw_multi_aff pw_multi_aff::scale_down(isl::val v) const
 {
-  if (!ptr || pnt.is_null())
+  if (!ptr || v.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_aff_eval(copy(), pnt.release());
+  auto res = isl_pw_multi_aff_scale_down_val(copy(), v.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::floor() const
+isl::pw_multi_aff pw_multi_aff::scale_down(long v) 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_floor(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->scale_down(isl::val(ctx(), v));
 }
 
-isl::set pw_aff::ge_set(isl::pw_aff pwaff2) const
+isl::multi_pw_aff pw_multi_aff::set_at(int pos, const isl::pw_aff &el) const
 {
-  if (!ptr || pwaff2.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_pw_aff_ge_set(copy(), pwaff2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_pw_aff(*this).set_at(pos, el);
 }
 
-isl::pw_aff pw_aff::gist(isl::set context) const
+isl::multi_union_pw_aff pw_multi_aff::set_at(int pos, const isl::union_pw_aff &el) const
 {
-  if (!ptr || context.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_pw_aff_gist(copy(), context.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_pw_aff(*this).set_at(pos, el);
 }
 
-isl::set pw_aff::gt_set(isl::pw_aff pwaff2) const
+isl::pw_multi_aff pw_multi_aff::set_range_tuple(isl::id id) const
 {
-  if (!ptr || pwaff2.is_null())
+  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_aff_gt_set(copy(), pwaff2.release());
+  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_aff pw_aff::insert_domain(isl::space domain) const
+isl::pw_multi_aff pw_multi_aff::set_range_tuple(const std::string &id) const
 {
-  if (!ptr || domain.is_null())
+  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_aff_insert_domain(copy(), domain.release());
+  auto res = isl_pw_multi_aff_get_space(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::intersect_domain(isl::set set) const
+isl::space pw_multi_aff::get_space() const
 {
-  if (!ptr || set.is_null())
+  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())
     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_intersect_domain(copy(), set.release());
+  auto res = isl_pw_multi_aff_sub(copy(), pma2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::intersect_params(isl::set set) const
+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())
     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_intersect_params(copy(), set.release());
+  auto res = isl_pw_multi_aff_subtract_domain(copy(), set.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool pw_aff::isa_aff() const
+isl::union_pw_multi_aff pw_multi_aff::subtract_domain(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_pw_aff_isa_aff(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::union_pw_multi_aff(*this).subtract_domain(space);
 }
 
-isl::set pw_aff::le_set(isl::pw_aff pwaff2) const
+isl::union_pw_multi_aff pw_multi_aff::subtract_domain(const isl::union_set &uset) const
 {
-  if (!ptr || pwaff2.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_pw_aff_le_set(copy(), pwaff2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_multi_aff(*this).subtract_domain(uset);
 }
 
-isl::set pw_aff::lt_set(isl::pw_aff pwaff2) const
+isl::pw_multi_aff pw_multi_aff::subtract_domain(const isl::basic_set &set) const
 {
-  if (!ptr || pwaff2.is_null())
+  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_aff_lt_set(copy(), pwaff2.release());
+  auto res = isl_pw_multi_aff_to_list(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::max(isl::pw_aff pwaff2) const
+isl::multi_pw_aff pw_multi_aff::to_multi_pw_aff() const
 {
-  if (!ptr || pwaff2.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_pw_aff_max(copy(), pwaff2.release());
+  auto res = isl_pw_multi_aff_to_multi_pw_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::min(isl::pw_aff pwaff2) const
+isl::union_pw_multi_aff pw_multi_aff::to_union_pw_multi_aff() const
 {
-  if (!ptr || pwaff2.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_pw_aff_min(copy(), pwaff2.release());
+  auto res = isl_pw_multi_aff_to_union_pw_multi_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::mod(isl::val mod) const
+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 || mod.is_null())
+  if (!ptr || pma2.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_aff_mod_val(copy(), mod.release());
+  auto res = isl_pw_multi_aff_union_add(copy(), pma2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::mod(long mod) const
+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 this->mod(isl::val(ctx(), mod));
+  return isl::union_pw_multi_aff(*this).union_add(upma2);
 }
 
-isl::pw_aff pw_aff::mul(isl::pw_aff pwaff2) const
+isl::pw_multi_aff pw_multi_aff::union_add(const isl::multi_aff &pma2) const
 {
-  if (!ptr || pwaff2.is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  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())
+    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_pw_aff_mul(copy(), pwaff2.release());
+  auto res = isl_pw_multi_aff_zero(space.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set pw_aff::ne_set(isl::pw_aff pwaff2) const
+inline std::ostream &operator<<(std::ostream &os, const pw_multi_aff &obj)
 {
-  if (!ptr || pwaff2.is_null())
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_pw_multi_aff_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_aff_ne_set(copy(), pwaff2.release());
-  if (!res)
+  char *str = isl_pw_multi_aff_to_str(obj.get());
+  if (!str)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  os << str;
+  free(str);
+  return os;
 }
 
-isl::pw_aff pw_aff::neg() const
-{
+// implementations for isl::pw_multi_aff_list
+pw_multi_aff_list manage(__isl_take isl_pw_multi_aff_list *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  return pw_multi_aff_list(ptr);
+}
+pw_multi_aff_list manage_copy(__isl_keep isl_pw_multi_aff_list *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_pw_multi_aff_list_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_aff_neg(copy());
-  if (!res)
+  ptr = isl_pw_multi_aff_list_copy(ptr);
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return pw_multi_aff_list(ptr);
 }
 
-isl::pw_aff pw_aff::param_on_domain(isl::set domain, isl::id id)
+pw_multi_aff_list::pw_multi_aff_list()
+    : ptr(nullptr) {}
+
+pw_multi_aff_list::pw_multi_aff_list(const pw_multi_aff_list &obj)
+    : ptr(nullptr)
 {
-  if (domain.is_null() || id.is_null())
+  if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = domain.ctx();
+  auto saved_ctx = isl_pw_multi_aff_list_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_aff_param_on_domain_id(domain.release(), id.release());
+  ptr = obj.copy();
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+}
+
+pw_multi_aff_list::pw_multi_aff_list(__isl_take isl_pw_multi_aff_list *ptr)
+    : ptr(ptr) {}
+
+pw_multi_aff_list::pw_multi_aff_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_pw_multi_aff_list_alloc(ctx.release(), n);
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  ptr = res;
 }
 
-isl::pw_aff pw_aff::pullback(isl::multi_aff ma) const
+pw_multi_aff_list::pw_multi_aff_list(isl::pw_multi_aff el)
 {
-  if (!ptr || ma.is_null())
+  if (el.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = el.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_aff_pullback_multi_aff(copy(), ma.release());
+  auto res = isl_pw_multi_aff_list_from_pw_multi_aff(el.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  ptr = res;
 }
 
-isl::pw_aff pw_aff::pullback(isl::multi_pw_aff mpa) const
+pw_multi_aff_list::pw_multi_aff_list(isl::ctx ctx, const std::string &str)
 {
-  if (!ptr || mpa.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = ctx;
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_aff_pullback_multi_pw_aff(copy(), mpa.release());
+  auto res = isl_pw_multi_aff_list_read_from_str(ctx.release(), str.c_str());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  ptr = res;
 }
 
-isl::pw_aff pw_aff::pullback(isl::pw_multi_aff pma) const
+pw_multi_aff_list &pw_multi_aff_list::operator=(pw_multi_aff_list obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+pw_multi_aff_list::~pw_multi_aff_list() {
+  if (ptr)
+    isl_pw_multi_aff_list_free(ptr);
+}
+
+__isl_give isl_pw_multi_aff_list *pw_multi_aff_list::copy() const & {
+  return isl_pw_multi_aff_list_copy(ptr);
+}
+
+__isl_keep isl_pw_multi_aff_list *pw_multi_aff_list::get() const {
+  return ptr;
+}
+
+__isl_give isl_pw_multi_aff_list *pw_multi_aff_list::release() {
+  isl_pw_multi_aff_list *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool pw_multi_aff_list::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx pw_multi_aff_list::ctx() const {
+  return isl::ctx(isl_pw_multi_aff_list_get_ctx(ptr));
+}
+
+isl::pw_multi_aff_list pw_multi_aff_list::add(isl::pw_multi_aff el) const
 {
-  if (!ptr || pma.is_null())
+  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_pw_aff_pullback_pw_multi_aff(copy(), pma.release());
+  auto res = isl_pw_multi_aff_list_add(copy(), el.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::scale(isl::val v) const
+isl::pw_multi_aff pw_multi_aff_list::at(int index) const
 {
-  if (!ptr || v.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_pw_aff_scale_val(copy(), v.release());
+  auto res = isl_pw_multi_aff_list_get_at(get(), index);
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::scale(long v) const
+isl::pw_multi_aff pw_multi_aff_list::get_at(int index) const
 {
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->scale(isl::val(ctx(), v));
+  return at(index);
 }
 
-isl::pw_aff pw_aff::scale_down(isl::val f) const
+isl::pw_multi_aff_list pw_multi_aff_list::clear() const
 {
-  if (!ptr || f.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_pw_aff_scale_down_val(copy(), f.release());
+  auto res = isl_pw_multi_aff_list_clear(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::scale_down(long f) const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->scale_down(isl::val(ctx(), f));
-}
-
-isl::pw_aff pw_aff::sub(isl::pw_aff pwaff2) const
+isl::pw_multi_aff_list pw_multi_aff_list::concat(isl::pw_multi_aff_list list2) const
 {
-  if (!ptr || pwaff2.is_null())
+  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_pw_aff_sub(copy(), pwaff2.release());
+  auto res = isl_pw_multi_aff_list_concat(copy(), list2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::subtract_domain(isl::set set) const
+isl::pw_multi_aff_list pw_multi_aff_list::drop(unsigned int first, unsigned int n) const
 {
-  if (!ptr || set.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_pw_aff_subtract_domain(copy(), set.release());
+  auto res = isl_pw_multi_aff_list_drop(copy(), first, n);
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::tdiv_q(isl::pw_aff pa2) const
+void pw_multi_aff_list::foreach(const std::function<void(isl::pw_multi_aff)> &fn) const
 {
-  if (!ptr || pa2.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_pw_aff_tdiv_q(copy(), pa2.release());
-  if (!res)
+  struct fn_data {
+    std::function<void(isl::pw_multi_aff)> func;
+    std::exception_ptr eptr;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_pw_multi_aff *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_pw_multi_aff_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 manage(res);
+  return;
 }
 
-isl::pw_aff pw_aff::tdiv_r(isl::pw_aff pa2) const
+isl::pw_multi_aff_list pw_multi_aff_list::insert(unsigned int pos, isl::pw_multi_aff el) const
 {
-  if (!ptr || pa2.is_null())
+  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_pw_aff_tdiv_r(copy(), pa2.release());
+  auto res = isl_pw_multi_aff_list_insert(copy(), pos, el.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff pw_aff::union_add(isl::pw_aff pwaff2) const
+unsigned pw_multi_aff_list::size() const
 {
-  if (!ptr || pwaff2.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_pw_aff_union_add(copy(), pwaff2.release());
-  if (!res)
+  auto res = isl_pw_multi_aff_list_size(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-inline std::ostream &operator<<(std::ostream &os, const pw_aff &obj)
+inline std::ostream &operator<<(std::ostream &os, const pw_multi_aff_list &obj)
 {
   if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_pw_aff_get_ctx(obj.get());
+  auto saved_ctx = isl_pw_multi_aff_list_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_pw_aff_to_str(obj.get());
+  char *str = isl_pw_multi_aff_list_to_str(obj.get());
   if (!str)
     exception::throw_last_error(saved_ctx);
   os << str;
@@ -11412,219 +19785,165 @@ inline std::ostream &operator<<(std::ostream &os, const pw_aff &obj)
   return os;
 }
 
-// implementations for isl::pw_aff_list
-pw_aff_list manage(__isl_take isl_pw_aff_list *ptr) {
+// implementations for isl::schedule
+schedule manage(__isl_take isl_schedule *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return pw_aff_list(ptr);
+  return schedule(ptr);
 }
-pw_aff_list manage_copy(__isl_keep isl_pw_aff_list *ptr) {
+schedule manage_copy(__isl_keep isl_schedule *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_pw_aff_list_get_ctx(ptr);
+  auto saved_ctx = isl_schedule_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_pw_aff_list_copy(ptr);
+  ptr = isl_schedule_copy(ptr);
   if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return pw_aff_list(ptr);
+  return schedule(ptr);
 }
 
-pw_aff_list::pw_aff_list()
+schedule::schedule()
     : ptr(nullptr) {}
 
-pw_aff_list::pw_aff_list(const pw_aff_list &obj)
+schedule::schedule(const schedule &obj)
     : ptr(nullptr)
 {
   if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_pw_aff_list_get_ctx(obj.ptr);
+  auto saved_ctx = isl_schedule_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);
 }
 
-pw_aff_list::pw_aff_list(__isl_take isl_pw_aff_list *ptr)
+schedule::schedule(__isl_take isl_schedule *ptr)
     : ptr(ptr) {}
 
-pw_aff_list::pw_aff_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_pw_aff_list_alloc(ctx.release(), n);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-pw_aff_list::pw_aff_list(isl::pw_aff el)
+schedule::schedule(isl::ctx ctx, const std::string &str)
 {
-  if (el.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = el.ctx();
+  auto saved_ctx = ctx;
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_aff_list_from_pw_aff(el.release());
+  auto res = isl_schedule_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) {
+schedule &schedule::operator=(schedule obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-pw_aff_list::~pw_aff_list() {
+schedule::~schedule() {
   if (ptr)
-    isl_pw_aff_list_free(ptr);
+    isl_schedule_free(ptr);
 }
 
-__isl_give isl_pw_aff_list *pw_aff_list::copy() const & {
-  return isl_pw_aff_list_copy(ptr);
+__isl_give isl_schedule *schedule::copy() const & {
+  return isl_schedule_copy(ptr);
 }
 
-__isl_keep isl_pw_aff_list *pw_aff_list::get() const {
+__isl_keep isl_schedule *schedule::get() const {
   return ptr;
 }
 
-__isl_give isl_pw_aff_list *pw_aff_list::release() {
-  isl_pw_aff_list *tmp = ptr;
+__isl_give isl_schedule *schedule::release() {
+  isl_schedule *tmp = ptr;
   ptr = nullptr;
   return tmp;
 }
 
-bool pw_aff_list::is_null() const {
+bool schedule::is_null() const {
   return ptr == nullptr;
 }
 
-isl::ctx pw_aff_list::ctx() const {
-  return isl::ctx(isl_pw_aff_list_get_ctx(ptr));
+isl::ctx schedule::ctx() const {
+  return isl::ctx(isl_schedule_get_ctx(ptr));
 }
 
-isl::pw_aff_list pw_aff_list::add(isl::pw_aff el) const
+isl::union_set schedule::domain() const
 {
-  if (!ptr || el.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_pw_aff_list_add(copy(), el.release());
+  auto res = isl_schedule_get_domain(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff_list pw_aff_list::clear() const
+isl::union_set schedule::get_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_pw_aff_list_clear(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return domain();
 }
 
-isl::pw_aff_list pw_aff_list::concat(isl::pw_aff_list list2) const
+isl::schedule schedule::from_domain(isl::union_set domain)
 {
-  if (!ptr || list2.is_null())
+  if (domain.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = domain.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_aff_list_concat(copy(), list2.release());
+  auto res = isl_schedule_from_domain(domain.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff_list pw_aff_list::drop(unsigned int first, unsigned int n) const
+isl::union_map schedule::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_list_drop(copy(), first, n);
+  auto res = isl_schedule_get_map(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-void pw_aff_list::foreach(const std::function<void(isl::pw_aff)> &fn) const
+isl::union_map schedule::get_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);
-  struct fn_data {
-    std::function<void(isl::pw_aff)> func;
-    std::exception_ptr eptr;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_pw_aff *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_pw_aff_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;
+  return map();
 }
 
-isl::pw_aff pw_aff_list::at(int index) const
+isl::schedule schedule::pullback(isl::union_pw_multi_aff upma) const
 {
-  if (!ptr)
+  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_pw_aff_list_get_at(get(), index);
+  auto res = isl_schedule_pullback_union_pw_multi_aff(copy(), upma.release());
   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
+isl::schedule_node schedule::root() const
 {
-  if (!ptr || el.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_pw_aff_list_insert(copy(), pos, el.release());
+  auto res = isl_schedule_get_root(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-unsigned pw_aff_list::size() const
+isl::schedule_node schedule::get_root() 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_size(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return root();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const pw_aff_list &obj)
+inline std::ostream &operator<<(std::ostream &os, const schedule &obj)
 {
   if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_pw_aff_list_get_ctx(obj.get());
+  auto saved_ctx = isl_schedule_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_pw_aff_list_to_str(obj.get());
+  char *str = isl_schedule_to_str(obj.get());
   if (!str)
     exception::throw_last_error(saved_ctx);
   os << str;
@@ -11632,1268 +19951,1429 @@ inline std::ostream &operator<<(std::ostream &os, const pw_aff_list &obj)
   return os;
 }
 
-// implementations for isl::pw_multi_aff
-pw_multi_aff manage(__isl_take isl_pw_multi_aff *ptr) {
+// implementations for isl::schedule_constraints
+schedule_constraints manage(__isl_take isl_schedule_constraints *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return pw_multi_aff(ptr);
+  return schedule_constraints(ptr);
 }
-pw_multi_aff manage_copy(__isl_keep isl_pw_multi_aff *ptr) {
+schedule_constraints manage_copy(__isl_keep isl_schedule_constraints *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_pw_multi_aff_get_ctx(ptr);
+  auto saved_ctx = isl_schedule_constraints_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_pw_multi_aff_copy(ptr);
+  ptr = isl_schedule_constraints_copy(ptr);
   if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return pw_multi_aff(ptr);
+  return schedule_constraints(ptr);
 }
 
-pw_multi_aff::pw_multi_aff()
+schedule_constraints::schedule_constraints()
     : ptr(nullptr) {}
 
-pw_multi_aff::pw_multi_aff(const pw_multi_aff &obj)
+schedule_constraints::schedule_constraints(const schedule_constraints &obj)
     : ptr(nullptr)
 {
   if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_pw_multi_aff_get_ctx(obj.ptr);
+  auto saved_ctx = isl_schedule_constraints_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);
 }
 
-pw_multi_aff::pw_multi_aff(__isl_take isl_pw_multi_aff *ptr)
+schedule_constraints::schedule_constraints(__isl_take isl_schedule_constraints *ptr)
     : ptr(ptr) {}
 
-pw_multi_aff::pw_multi_aff(isl::multi_aff ma)
-{
-  if (ma.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ma.ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_multi_aff_from_multi_aff(ma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-pw_multi_aff::pw_multi_aff(isl::pw_aff pa)
-{
-  if (pa.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = pa.ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_multi_aff_from_pw_aff(pa.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-pw_multi_aff::pw_multi_aff(isl::ctx ctx, const std::string &str)
+schedule_constraints::schedule_constraints(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_read_from_str(ctx.release(), str.c_str());
+  auto res = isl_schedule_constraints_read_from_str(ctx.release(), str.c_str());
   if (!res)
     exception::throw_last_error(saved_ctx);
   ptr = res;
 }
 
-pw_multi_aff &pw_multi_aff::operator=(pw_multi_aff obj) {
+schedule_constraints &schedule_constraints::operator=(schedule_constraints obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-pw_multi_aff::~pw_multi_aff() {
+schedule_constraints::~schedule_constraints() {
   if (ptr)
-    isl_pw_multi_aff_free(ptr);
+    isl_schedule_constraints_free(ptr);
 }
 
-__isl_give isl_pw_multi_aff *pw_multi_aff::copy() const & {
-  return isl_pw_multi_aff_copy(ptr);
+__isl_give isl_schedule_constraints *schedule_constraints::copy() const & {
+  return isl_schedule_constraints_copy(ptr);
 }
 
-__isl_keep isl_pw_multi_aff *pw_multi_aff::get() const {
+__isl_keep isl_schedule_constraints *schedule_constraints::get() const {
   return ptr;
 }
 
-__isl_give isl_pw_multi_aff *pw_multi_aff::release() {
-  isl_pw_multi_aff *tmp = ptr;
+__isl_give isl_schedule_constraints *schedule_constraints::release() {
+  isl_schedule_constraints *tmp = ptr;
   ptr = nullptr;
   return tmp;
 }
 
-bool pw_multi_aff::is_null() const {
+bool schedule_constraints::is_null() const {
   return ptr == nullptr;
 }
 
-isl::ctx pw_multi_aff::ctx() const {
-  return isl::ctx(isl_pw_multi_aff_get_ctx(ptr));
+isl::ctx schedule_constraints::ctx() const {
+  return isl::ctx(isl_schedule_constraints_get_ctx(ptr));
 }
 
-isl::pw_multi_aff pw_multi_aff::add(isl::pw_multi_aff pma2) const
+isl::union_map schedule_constraints::coincidence() const
 {
-  if (!ptr || pma2.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_pw_multi_aff_add(copy(), pma2.release());
+  auto res = isl_schedule_constraints_get_coincidence(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::add_constant(isl::multi_val mv) const
+isl::union_map schedule_constraints::get_coincidence() const
 {
-  if (!ptr || mv.is_null())
+  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_pw_multi_aff_add_constant_multi_val(copy(), mv.release());
+  auto res = isl_schedule_constraints_compute_schedule(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::add_constant(isl::val v) const
+isl::union_map schedule_constraints::conditional_validity() const
 {
-  if (!ptr || v.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_pw_multi_aff_add_constant_val(copy(), v.release());
+  auto res = isl_schedule_constraints_get_conditional_validity(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::add_constant(long v) const
+isl::union_map schedule_constraints::get_conditional_validity() const
+{
+  return conditional_validity();
+}
+
+isl::union_map schedule_constraints::conditional_validity_condition() const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->add_constant(isl::val(ctx(), v));
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_constraints_get_conditional_validity_condition(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::multi_aff pw_multi_aff::as_multi_aff() const
+isl::union_map schedule_constraints::get_conditional_validity_condition() const
+{
+  return conditional_validity_condition();
+}
+
+isl::set schedule_constraints::context() 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_multi_aff(copy());
+  auto res = isl_schedule_constraints_get_context(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::set schedule_constraints::get_context() const
+{
+  return context();
+}
+
+isl::union_set schedule_constraints::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_schedule_constraints_get_domain(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::bind_domain(isl::multi_id tuple) const
+isl::union_set schedule_constraints::get_domain() const
+{
+  return domain();
+}
+
+isl::schedule_constraints schedule_constraints::on_domain(isl::union_set domain)
 {
-  if (!ptr || tuple.is_null())
+  if (domain.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = domain.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_multi_aff_bind_domain(copy(), tuple.release());
+  auto res = isl_schedule_constraints_on_domain(domain.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::bind_domain_wrapped_domain(isl::multi_id tuple) const
+isl::union_map schedule_constraints::proximity() const
 {
-  if (!ptr || tuple.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_pw_multi_aff_bind_domain_wrapped_domain(copy(), tuple.release());
+  auto res = isl_schedule_constraints_get_proximity(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::coalesce() const
+isl::union_map schedule_constraints::get_proximity() const
 {
-  if (!ptr)
+  return proximity();
+}
+
+isl::schedule_constraints schedule_constraints::set_coincidence(isl::union_map coincidence) const
+{
+  if (!ptr || coincidence.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_coalesce(copy());
+  auto res = isl_schedule_constraints_set_coincidence(copy(), coincidence.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set pw_multi_aff::domain() const
+isl::schedule_constraints schedule_constraints::set_conditional_validity(isl::union_map condition, isl::union_map validity) const
 {
-  if (!ptr)
+  if (!ptr || condition.is_null() || validity.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_domain(copy());
+  auto res = isl_schedule_constraints_set_conditional_validity(copy(), condition.release(), validity.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::domain_map(isl::space space)
+isl::schedule_constraints schedule_constraints::set_context(isl::set context) const
 {
-  if (space.is_null())
+  if (!ptr || context.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_multi_aff_domain_map(space.release());
+  auto res = isl_schedule_constraints_set_context(copy(), context.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::flat_range_product(isl::pw_multi_aff pma2) const
+isl::schedule_constraints schedule_constraints::set_proximity(isl::union_map proximity) const
 {
-  if (!ptr || pma2.is_null())
+  if (!ptr || proximity.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_flat_range_product(copy(), pma2.release());
+  auto res = isl_schedule_constraints_set_proximity(copy(), proximity.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-void pw_multi_aff::foreach_piece(const std::function<void(isl::set, isl::multi_aff)> &fn) const
+isl::schedule_constraints schedule_constraints::set_validity(isl::union_map validity) const
 {
-  if (!ptr)
+  if (!ptr || validity.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);
-  struct fn_data {
-    std::function<void(isl::set, isl::multi_aff)> func;
-    std::exception_ptr eptr;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_set *arg_0, isl_multi_aff *arg_1, void *arg_2) -> isl_stat {
-    auto *data = static_cast<struct fn_data *>(arg_2);
-    ISL_CPP_TRY {
-      (data->func)(manage(arg_0), manage(arg_1));
-      return isl_stat_ok;
-    } ISL_CPP_CATCH_ALL {
-      data->eptr = std::current_exception();
-      return isl_stat_error;
-    }
-  };
-  auto res = isl_pw_multi_aff_foreach_piece(get(), fn_lambda, &fn_data);
-  if (fn_data.eptr)
-    std::rethrow_exception(fn_data.eptr);
-  if (res < 0)
+  auto res = isl_schedule_constraints_set_validity(copy(), validity.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return;
+  return manage(res);
 }
 
-isl::space pw_multi_aff::space() const
+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_pw_multi_aff_get_space(get());
+  auto res = isl_schedule_constraints_get_validity(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space pw_multi_aff::get_space() const
+isl::union_map schedule_constraints::get_validity() const
 {
-  return space();
+  return validity();
 }
 
-isl::pw_multi_aff pw_multi_aff::gist(isl::set set) const
+inline std::ostream &operator<<(std::ostream &os, const schedule_constraints &obj)
 {
-  if (!ptr || set.is_null())
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_schedule_constraints_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_multi_aff_gist(copy(), set.release());
-  if (!res)
+  char *str = isl_schedule_constraints_to_str(obj.get());
+  if (!str)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  os << str;
+  free(str);
+  return os;
 }
 
-isl::pw_multi_aff pw_multi_aff::identity_on_domain(isl::space space)
-{
-  if (space.is_null())
+// implementations for isl::schedule_node
+schedule_node manage(__isl_take isl_schedule_node *ptr) {
+  if (!ptr)
     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_pw_multi_aff_identity_on_domain_space(space.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return schedule_node(ptr);
 }
-
-isl::pw_multi_aff pw_multi_aff::insert_domain(isl::space domain) const
-{
-  if (!ptr || domain.is_null())
+schedule_node manage_copy(__isl_keep isl_schedule_node *ptr) {
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_schedule_node_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_multi_aff_insert_domain(copy(), domain.release());
-  if (!res)
+  ptr = isl_schedule_node_copy(ptr);
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return schedule_node(ptr);
 }
 
-isl::pw_multi_aff pw_multi_aff::intersect_domain(isl::set set) const
+schedule_node::schedule_node()
+    : ptr(nullptr) {}
+
+schedule_node::schedule_node(const schedule_node &obj)
+    : ptr(nullptr)
 {
-  if (!ptr || set.is_null())
+  if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_schedule_node_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_multi_aff_intersect_domain(copy(), set.release());
-  if (!res)
+  ptr = obj.copy();
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::intersect_params(isl::set set) const
+schedule_node::schedule_node(__isl_take isl_schedule_node *ptr)
+    : ptr(ptr) {}
+
+schedule_node &schedule_node::operator=(schedule_node obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+schedule_node::~schedule_node() {
+  if (ptr)
+    isl_schedule_node_free(ptr);
+}
+
+__isl_give isl_schedule_node *schedule_node::copy() const & {
+  return isl_schedule_node_copy(ptr);
+}
+
+__isl_keep isl_schedule_node *schedule_node::get() const {
+  return ptr;
+}
+
+__isl_give isl_schedule_node *schedule_node::release() {
+  isl_schedule_node *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool schedule_node::is_null() const {
+  return ptr == nullptr;
+}
+
+template <typename T, typename>
+bool schedule_node::isa_type(T subtype) const
 {
-  if (!ptr || set.is_null())
+  if (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_intersect_params(copy(), set.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl_schedule_node_get_type(get()) == subtype;
+}
+template <class T>
+bool schedule_node::isa() const
+{
+  return isa_type<decltype(T::type)>(T::type);
+}
+template <class T>
+T schedule_node::as() const
+{
+ if (!isa<T>())
+    exception::throw_invalid("not an object of the requested subtype", __FILE__, __LINE__);
+  return T(copy());
 }
 
-bool pw_multi_aff::involves_locals() const
+isl::ctx schedule_node::ctx() const {
+  return isl::ctx(isl_schedule_node_get_ctx(ptr));
+}
+
+isl::schedule_node schedule_node::ancestor(int generation) 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_involves_locals(get());
-  if (res < 0)
+  auto res = isl_schedule_node_ancestor(copy(), generation);
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-bool pw_multi_aff::isa_multi_aff() const
+unsigned schedule_node::ancestor_child_position(const isl::schedule_node &ancestor) const
 {
-  if (!ptr)
+  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_pw_multi_aff_isa_multi_aff(get());
+  auto res = isl_schedule_node_get_ancestor_child_position(get(), ancestor.get());
   if (res < 0)
     exception::throw_last_error(saved_ctx);
   return res;
 }
 
-isl::multi_val pw_multi_aff::max_multi_val() const
+unsigned schedule_node::get_ancestor_child_position(const isl::schedule_node &ancestor) 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_max_multi_val(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return ancestor_child_position(ancestor);
 }
 
-isl::multi_val pw_multi_aff::min_multi_val() const
+isl::schedule_node schedule_node::child(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_min_multi_val(copy());
+  auto res = isl_schedule_node_child(copy(), pos);
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-unsigned pw_multi_aff::n_piece() const
+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_pw_multi_aff_n_piece(get());
+  auto res = isl_schedule_node_get_child_position(get());
   if (res < 0)
     exception::throw_last_error(saved_ctx);
   return res;
 }
 
-isl::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(isl::pw_multi_aff pma2) const
+unsigned schedule_node::get_child_position() const
 {
-  if (!ptr || pma2.is_null())
+  return child_position();
+}
+
+bool schedule_node::every_descendant(const std::function<bool(isl::schedule_node)> &test) 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_preimage_domain_wrapped_domain_pw_multi_aff(copy(), pma2.release());
-  if (!res)
+  struct test_data {
+    std::function<bool(isl::schedule_node)> func;
+    std::exception_ptr eptr;
+  } test_data = { test };
+  auto test_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_bool {
+    auto *data = static_cast<struct test_data *>(arg_1);
+    ISL_CPP_TRY {
+      auto ret = (data->func)(manage_copy(arg_0));
+      return ret ? isl_bool_true : isl_bool_false;
+    } ISL_CPP_CATCH_ALL {
+      data->eptr = std::current_exception();
+      return isl_bool_error;
+    }
+  };
+  auto res = isl_schedule_node_every_descendant(get(), test_lambda, &test_data);
+  if (test_data.eptr)
+    std::rethrow_exception(test_data.eptr);
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::pw_multi_aff pw_multi_aff::product(isl::pw_multi_aff pma2) const
+isl::schedule_node schedule_node::first_child() const
 {
-  if (!ptr || pma2.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_pw_multi_aff_product(copy(), pma2.release());
+  auto res = isl_schedule_node_first_child(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::pullback(isl::multi_aff ma) const
+void schedule_node::foreach_ancestor_top_down(const std::function<void(isl::schedule_node)> &fn) const
 {
-  if (!ptr || ma.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_pw_multi_aff_pullback_multi_aff(copy(), ma.release());
-  if (!res)
+  struct fn_data {
+    std::function<void(isl::schedule_node)> func;
+    std::exception_ptr eptr;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_stat {
+    auto *data = static_cast<struct fn_data *>(arg_1);
+    ISL_CPP_TRY {
+      (data->func)(manage_copy(arg_0));
+      return isl_stat_ok;
+    } ISL_CPP_CATCH_ALL {
+      data->eptr = std::current_exception();
+      return isl_stat_error;
+    }
+  };
+  auto res = isl_schedule_node_foreach_ancestor_top_down(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 manage(res);
+  return;
 }
 
-isl::pw_multi_aff pw_multi_aff::pullback(isl::pw_multi_aff pma2) const
+void schedule_node::foreach_descendant_top_down(const std::function<bool(isl::schedule_node)> &fn) const
 {
-  if (!ptr || pma2.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_pw_multi_aff_pullback_pw_multi_aff(copy(), pma2.release());
-  if (!res)
+  struct fn_data {
+    std::function<bool(isl::schedule_node)> func;
+    std::exception_ptr eptr;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_bool {
+    auto *data = static_cast<struct fn_data *>(arg_1);
+    ISL_CPP_TRY {
+      auto ret = (data->func)(manage_copy(arg_0));
+      return ret ? isl_bool_true : isl_bool_false;
+    } ISL_CPP_CATCH_ALL {
+      data->eptr = std::current_exception();
+      return isl_bool_error;
+    }
+  };
+  auto res = isl_schedule_node_foreach_descendant_top_down(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 manage(res);
+  return;
 }
 
-isl::pw_multi_aff pw_multi_aff::range_factor_domain() const
+isl::schedule_node schedule_node::from_domain(isl::union_set domain)
 {
-  if (!ptr)
+  if (domain.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = domain.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_multi_aff_range_factor_domain(copy());
+  auto res = isl_schedule_node_from_domain(domain.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::range_factor_range() const
+isl::schedule_node schedule_node::from_extension(isl::union_map extension)
 {
-  if (!ptr)
+  if (extension.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = extension.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_multi_aff_range_factor_range(copy());
+  auto res = isl_schedule_node_from_extension(extension.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::range_map(isl::space space)
+isl::schedule_node schedule_node::graft_after(isl::schedule_node graft) const
 {
-  if (space.is_null())
+  if (!ptr || graft.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_multi_aff_range_map(space.release());
+  auto res = isl_schedule_node_graft_after(copy(), graft.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::range_product(isl::pw_multi_aff pma2) const
+isl::schedule_node schedule_node::graft_before(isl::schedule_node graft) const
 {
-  if (!ptr || pma2.is_null())
+  if (!ptr || graft.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_range_product(copy(), pma2.release());
+  auto res = isl_schedule_node_graft_before(copy(), graft.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::scale(isl::val v) const
+bool schedule_node::has_children() const
 {
-  if (!ptr || v.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_pw_multi_aff_scale_val(copy(), v.release());
-  if (!res)
+  auto res = isl_schedule_node_has_children(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::pw_multi_aff pw_multi_aff::scale(long v) const
+bool schedule_node::has_next_sibling() const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->scale(isl::val(ctx(), v));
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_node_has_next_sibling(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
 }
 
-isl::pw_multi_aff pw_multi_aff::scale_down(isl::val v) const
+bool schedule_node::has_parent() const
 {
-  if (!ptr || v.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_pw_multi_aff_scale_down_val(copy(), v.release());
-  if (!res)
+  auto res = isl_schedule_node_has_parent(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::pw_multi_aff pw_multi_aff::scale_down(long v) const
+bool schedule_node::has_previous_sibling() const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->scale_down(isl::val(ctx(), v));
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_node_has_previous_sibling(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
 }
 
-isl::pw_multi_aff pw_multi_aff::sub(isl::pw_multi_aff pma2) const
+isl::schedule_node schedule_node::insert_context(isl::set context) const
 {
-  if (!ptr || pma2.is_null())
+  if (!ptr || context.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_sub(copy(), pma2.release());
+  auto res = isl_schedule_node_insert_context(copy(), context.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::subtract_domain(isl::set set) const
+isl::schedule_node schedule_node::insert_filter(isl::union_set filter) const
 {
-  if (!ptr || set.is_null())
+  if (!ptr || filter.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_subtract_domain(copy(), set.release());
+  auto res = isl_schedule_node_insert_filter(copy(), filter.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::union_add(isl::pw_multi_aff pma2) const
+isl::schedule_node schedule_node::insert_guard(isl::set context) const
 {
-  if (!ptr || pma2.is_null())
+  if (!ptr || context.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_union_add(copy(), pma2.release());
+  auto res = isl_schedule_node_insert_guard(copy(), context.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff::zero(isl::space space)
+isl::schedule_node schedule_node::insert_mark(isl::id mark) const
 {
-  if (space.is_null())
+  if (!ptr || mark.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_multi_aff_zero(space.release());
+  auto res = isl_schedule_node_insert_mark(copy(), mark.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const pw_multi_aff &obj)
+isl::schedule_node schedule_node::insert_mark(const std::string &mark) const
 {
-  if (!obj.get())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_pw_multi_aff_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_pw_multi_aff_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
-}
-
-// implementations for isl::pw_multi_aff_list
-pw_multi_aff_list manage(__isl_take isl_pw_multi_aff_list *ptr) {
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return pw_multi_aff_list(ptr);
-}
-pw_multi_aff_list manage_copy(__isl_keep isl_pw_multi_aff_list *ptr) {
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_pw_multi_aff_list_get_ctx(ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_pw_multi_aff_list_copy(ptr);
   if (!ptr)
-    exception::throw_last_error(saved_ctx);
-  return pw_multi_aff_list(ptr);
-}
-
-pw_multi_aff_list::pw_multi_aff_list()
-    : ptr(nullptr) {}
-
-pw_multi_aff_list::pw_multi_aff_list(const pw_multi_aff_list &obj)
-    : ptr(nullptr)
-{
-  if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_pw_multi_aff_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);
-}
-
-pw_multi_aff_list::pw_multi_aff_list(__isl_take isl_pw_multi_aff_list *ptr)
-    : ptr(ptr) {}
-
-pw_multi_aff_list::pw_multi_aff_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_pw_multi_aff_list_alloc(ctx.release(), n);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return this->insert_mark(isl::id(ctx(), mark));
 }
 
-pw_multi_aff_list::pw_multi_aff_list(isl::pw_multi_aff el)
+isl::schedule_node schedule_node::insert_partial_schedule(isl::multi_union_pw_aff schedule) const
 {
-  if (el.is_null())
+  if (!ptr || schedule.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = el.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_multi_aff_list_from_pw_multi_aff(el.release());
+  auto res = isl_schedule_node_insert_partial_schedule(copy(), schedule.release());
   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;
-}
-
-pw_multi_aff_list::~pw_multi_aff_list() {
-  if (ptr)
-    isl_pw_multi_aff_list_free(ptr);
-}
-
-__isl_give isl_pw_multi_aff_list *pw_multi_aff_list::copy() const & {
-  return isl_pw_multi_aff_list_copy(ptr);
-}
-
-__isl_keep isl_pw_multi_aff_list *pw_multi_aff_list::get() const {
-  return ptr;
-}
-
-__isl_give isl_pw_multi_aff_list *pw_multi_aff_list::release() {
-  isl_pw_multi_aff_list *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
-}
-
-bool pw_multi_aff_list::is_null() const {
-  return ptr == nullptr;
-}
-
-isl::ctx pw_multi_aff_list::ctx() const {
-  return isl::ctx(isl_pw_multi_aff_list_get_ctx(ptr));
+  return manage(res);
 }
 
-isl::pw_multi_aff_list pw_multi_aff_list::add(isl::pw_multi_aff el) const
+isl::schedule_node schedule_node::insert_sequence(isl::union_set_list filters) const
 {
-  if (!ptr || el.is_null())
+  if (!ptr || filters.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_list_add(copy(), el.release());
+  auto res = isl_schedule_node_insert_sequence(copy(), filters.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff_list pw_multi_aff_list::clear() const
+isl::schedule_node schedule_node::insert_set(isl::union_set_list filters) const
 {
-  if (!ptr)
+  if (!ptr || filters.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_list_clear(copy());
+  auto res = isl_schedule_node_insert_set(copy(), filters.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff_list pw_multi_aff_list::concat(isl::pw_multi_aff_list list2) const
+bool schedule_node::is_equal(const isl::schedule_node &node2) const
 {
-  if (!ptr || list2.is_null())
+  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_pw_multi_aff_list_concat(copy(), list2.release());
-  if (!res)
+  auto res = isl_schedule_node_is_equal(get(), node2.get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::pw_multi_aff_list pw_multi_aff_list::drop(unsigned int first, unsigned int n) const
+bool schedule_node::is_subtree_anchored() 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_drop(copy(), first, n);
-  if (!res)
+  auto res = isl_schedule_node_is_subtree_anchored(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-void pw_multi_aff_list::foreach(const std::function<void(isl::pw_multi_aff)> &fn) const
+isl::schedule_node schedule_node::map_descendant_bottom_up(const std::function<isl::schedule_node(isl::schedule_node)> &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::pw_multi_aff)> func;
+    std::function<isl::schedule_node(isl::schedule_node)> func;
     std::exception_ptr eptr;
   } fn_data = { fn };
-  auto fn_lambda = [](isl_pw_multi_aff *arg_0, void *arg_1) -> isl_stat {
+  auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_schedule_node * {
     auto *data = static_cast<struct fn_data *>(arg_1);
     ISL_CPP_TRY {
-      (data->func)(manage(arg_0));
-      return isl_stat_ok;
+      auto ret = (data->func)(manage(arg_0));
+      return ret.release();
     } ISL_CPP_CATCH_ALL {
       data->eptr = std::current_exception();
-      return isl_stat_error;
+      return NULL;
     }
   };
-  auto res = isl_pw_multi_aff_list_foreach(get(), fn_lambda, &fn_data);
+  auto res = isl_schedule_node_map_descendant_bottom_up(copy(), fn_lambda, &fn_data);
   if (fn_data.eptr)
     std::rethrow_exception(fn_data.eptr);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+unsigned schedule_node::n_children() 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_n_children(get());
   if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return;
+  return res;
 }
 
-isl::pw_multi_aff pw_multi_aff_list::at(int index) const
+isl::schedule_node schedule_node::next_sibling() 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);
+  auto res = isl_schedule_node_next_sibling(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff pw_multi_aff_list::get_at(int index) const
+isl::schedule_node schedule_node::order_after(isl::union_set filter) const
 {
-  return at(index);
+  if (!ptr || filter.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_order_after(copy(), filter.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::pw_multi_aff_list pw_multi_aff_list::insert(unsigned int pos, isl::pw_multi_aff el) const
+isl::schedule_node schedule_node::order_before(isl::union_set filter) const
 {
-  if (!ptr || el.is_null())
+  if (!ptr || filter.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_list_insert(copy(), pos, el.release());
+  auto res = isl_schedule_node_order_before(copy(), filter.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-unsigned pw_multi_aff_list::size() const
+isl::schedule_node schedule_node::parent() 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_size(get());
-  if (res < 0)
+  auto res = isl_schedule_node_parent(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const pw_multi_aff_list &obj)
+isl::multi_union_pw_aff schedule_node::prefix_schedule_multi_union_pw_aff() const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_pw_multi_aff_list_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_pw_multi_aff_list_to_str(obj.get());
-  if (!str)
+  auto res = isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(get());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::schedule
-schedule manage(__isl_take isl_schedule *ptr) {
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return schedule(ptr);
+isl::multi_union_pw_aff schedule_node::get_prefix_schedule_multi_union_pw_aff() const
+{
+  return prefix_schedule_multi_union_pw_aff();
 }
-schedule manage_copy(__isl_keep isl_schedule *ptr) {
+
+isl::union_map schedule_node::prefix_schedule_union_map() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_get_ctx(ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_schedule_copy(ptr);
-  if (!ptr)
+  auto res = isl_schedule_node_get_prefix_schedule_union_map(get());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return schedule(ptr);
+  return manage(res);
 }
 
-schedule::schedule()
-    : ptr(nullptr) {}
+isl::union_map schedule_node::get_prefix_schedule_union_map() const
+{
+  return prefix_schedule_union_map();
+}
 
-schedule::schedule(const schedule &obj)
-    : ptr(nullptr)
+isl::union_pw_multi_aff schedule_node::prefix_schedule_union_pw_multi_aff() const
 {
-  if (!obj.ptr)
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_get_ctx(obj.ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = obj.copy();
-  if (!ptr)
+  auto res = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(get());
+  if (!res)
     exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-schedule::schedule(__isl_take isl_schedule *ptr)
-    : ptr(ptr) {}
+isl::union_pw_multi_aff schedule_node::get_prefix_schedule_union_pw_multi_aff() const
+{
+  return prefix_schedule_union_pw_multi_aff();
+}
 
-schedule::schedule(isl::ctx ctx, const std::string &str)
+isl::schedule_node schedule_node::previous_sibling() const
 {
-  auto saved_ctx = ctx;
+  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_read_from_str(ctx.release(), str.c_str());
+  auto res = isl_schedule_node_previous_sibling(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-schedule &schedule::operator=(schedule obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+isl::schedule_node schedule_node::root() 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_root(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-schedule::~schedule() {
-  if (ptr)
-    isl_schedule_free(ptr);
+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_give isl_schedule *schedule::copy() const & {
-  return isl_schedule_copy(ptr);
+isl::schedule schedule_node::get_schedule() const
+{
+  return schedule();
 }
 
-__isl_keep isl_schedule *schedule::get() const {
-  return ptr;
+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_give isl_schedule *schedule::release() {
-  isl_schedule *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+isl::schedule_node schedule_node::get_shared_ancestor(const isl::schedule_node &node2) const
+{
+  return shared_ancestor(node2);
 }
 
-bool schedule::is_null() const {
-  return ptr == nullptr;
+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;
 }
 
-isl::ctx schedule::ctx() const {
-  return isl::ctx(isl_schedule_get_ctx(ptr));
+unsigned schedule_node::get_tree_depth() const
+{
+  return tree_depth();
 }
 
-isl::schedule schedule::from_domain(isl::union_set domain)
+inline std::ostream &operator<<(std::ostream &os, const schedule_node &obj)
 {
-  if (domain.is_null())
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = domain.ctx();
+  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_from_domain(domain.release());
-  if (!res)
+  char *str = isl_schedule_node_to_str(obj.get());
+  if (!str)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::schedule_node_band
+schedule_node_band::schedule_node_band()
+    : schedule_node() {}
+
+schedule_node_band::schedule_node_band(const schedule_node_band &obj)
+    : schedule_node(obj)
+{
+}
+
+schedule_node_band::schedule_node_band(__isl_take isl_schedule_node *ptr)
+    : schedule_node(ptr) {}
+
+schedule_node_band &schedule_node_band::operator=(schedule_node_band obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx schedule_node_band::ctx() const {
+  return isl::ctx(isl_schedule_node_get_ctx(ptr));
 }
 
-isl::union_set schedule::domain() const
+isl::union_set schedule_node_band::ast_build_options() 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_get_domain(get());
+  auto res = isl_schedule_node_band_get_ast_build_options(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_set schedule::get_domain() const
+isl::union_set schedule_node_band::get_ast_build_options() const
 {
-  return domain();
+  return ast_build_options();
 }
 
-isl::union_map schedule::map() const
+isl::set schedule_node_band::ast_isolate_option() 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_get_map(get());
+  auto res = isl_schedule_node_band_get_ast_isolate_option(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map schedule::get_map() const
+isl::set schedule_node_band::get_ast_isolate_option() const
 {
-  return map();
+  return ast_isolate_option();
 }
 
-isl::schedule_node schedule::root() const
+bool schedule_node_band::member_get_coincident(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_schedule_get_root(get());
-  if (!res)
+  auto res = isl_schedule_node_band_member_get_coincident(get(), pos);
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::schedule_node schedule::get_root() const
-{
-  return root();
+  return res;
 }
 
-isl::schedule schedule::pullback(isl::union_pw_multi_aff upma) const
+schedule_node_band schedule_node_band::member_set_coincident(int pos, int coincident) const
 {
-  if (!ptr || upma.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_schedule_pullback_union_pw_multi_aff(copy(), upma.release());
+  auto res = isl_schedule_node_band_member_set_coincident(copy(), pos, coincident);
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return manage(res).as<schedule_node_band>();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const schedule &obj)
+schedule_node_band schedule_node_band::mod(isl::multi_val mv) const
 {
-  if (!obj.get())
+  if (!ptr || mv.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_schedule_to_str(obj.get());
-  if (!str)
+  auto res = isl_schedule_node_band_mod(copy(), mv.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res).as<schedule_node_band>();
 }
 
-// implementations for isl::schedule_constraints
-schedule_constraints manage(__isl_take isl_schedule_constraints *ptr) {
+unsigned schedule_node_band::n_member() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return schedule_constraints(ptr);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_node_band_n_member(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
 }
-schedule_constraints manage_copy(__isl_keep isl_schedule_constraints *ptr) {
+
+isl::multi_union_pw_aff schedule_node_band::partial_schedule() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_constraints_get_ctx(ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_schedule_constraints_copy(ptr);
-  if (!ptr)
+  auto res = isl_schedule_node_band_get_partial_schedule(get());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return schedule_constraints(ptr);
+  return manage(res);
 }
 
-schedule_constraints::schedule_constraints()
-    : ptr(nullptr) {}
+isl::multi_union_pw_aff schedule_node_band::get_partial_schedule() const
+{
+  return partial_schedule();
+}
 
-schedule_constraints::schedule_constraints(const schedule_constraints &obj)
-    : ptr(nullptr)
+bool schedule_node_band::permutable() const
 {
-  if (!obj.ptr)
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_constraints_get_ctx(obj.ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = obj.copy();
-  if (!ptr)
+  auto res = isl_schedule_node_band_get_permutable(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
+  return res;
 }
 
-schedule_constraints::schedule_constraints(__isl_take isl_schedule_constraints *ptr)
-    : ptr(ptr) {}
+bool schedule_node_band::get_permutable() const
+{
+  return permutable();
+}
 
-schedule_constraints::schedule_constraints(isl::ctx ctx, const std::string &str)
+schedule_node_band schedule_node_band::scale(isl::multi_val mv) const
 {
-  auto saved_ctx = ctx;
+  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_schedule_constraints_read_from_str(ctx.release(), str.c_str());
+  auto res = isl_schedule_node_band_scale(copy(), mv.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-schedule_constraints &schedule_constraints::operator=(schedule_constraints obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-schedule_constraints::~schedule_constraints() {
-  if (ptr)
-    isl_schedule_constraints_free(ptr);
-}
-
-__isl_give isl_schedule_constraints *schedule_constraints::copy() const & {
-  return isl_schedule_constraints_copy(ptr);
-}
-
-__isl_keep isl_schedule_constraints *schedule_constraints::get() const {
-  return ptr;
-}
-
-__isl_give isl_schedule_constraints *schedule_constraints::release() {
-  isl_schedule_constraints *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+  return manage(res).as<schedule_node_band>();
 }
 
-bool schedule_constraints::is_null() const {
-  return ptr == nullptr;
+schedule_node_band schedule_node_band::scale_down(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_schedule_node_band_scale_down(copy(), mv.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res).as<schedule_node_band>();
 }
 
-isl::ctx schedule_constraints::ctx() const {
-  return isl::ctx(isl_schedule_constraints_get_ctx(ptr));
+schedule_node_band schedule_node_band::set_ast_build_options(isl::union_set options) const
+{
+  if (!ptr || options.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_band_set_ast_build_options(copy(), options.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res).as<schedule_node_band>();
 }
 
-isl::schedule schedule_constraints::compute_schedule() const
+schedule_node_band schedule_node_band::set_permutable(int 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_constraints_compute_schedule(copy());
+  auto res = isl_schedule_node_band_set_permutable(copy(), permutable);
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return manage(res).as<schedule_node_band>();
 }
 
-isl::union_map schedule_constraints::coincidence() const
+schedule_node_band schedule_node_band::shift(isl::multi_union_pw_aff shift) const
 {
-  if (!ptr)
+  if (!ptr || shift.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_constraints_get_coincidence(get());
+  auto res = isl_schedule_node_band_shift(copy(), shift.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return manage(res).as<schedule_node_band>();
 }
 
-isl::union_map schedule_constraints::get_coincidence() const
+schedule_node_band schedule_node_band::split(int pos) const
 {
-  return coincidence();
+  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_split(copy(), pos);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res).as<schedule_node_band>();
 }
 
-isl::union_map schedule_constraints::conditional_validity() const
+schedule_node_band schedule_node_band::tile(isl::multi_val sizes) const
 {
-  if (!ptr)
+  if (!ptr || sizes.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_constraints_get_conditional_validity(get());
+  auto res = isl_schedule_node_band_tile(copy(), sizes.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return manage(res).as<schedule_node_band>();
 }
 
-isl::union_map schedule_constraints::get_conditional_validity() const
+schedule_node_band schedule_node_band::member_set_ast_loop_default(int pos) const
 {
-  return conditional_validity();
+  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_member_set_ast_loop_type(copy(), pos, isl_ast_loop_default);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res).as<schedule_node_band>();
 }
 
-isl::union_map schedule_constraints::conditional_validity_condition() const
+schedule_node_band schedule_node_band::member_set_ast_loop_atomic(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_schedule_constraints_get_conditional_validity_condition(get());
+  auto res = isl_schedule_node_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_atomic);
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return manage(res).as<schedule_node_band>();
 }
 
-isl::union_map schedule_constraints::get_conditional_validity_condition() const
+schedule_node_band schedule_node_band::member_set_ast_loop_unroll(int pos) const
 {
-  return conditional_validity_condition();
+  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_member_set_ast_loop_type(copy(), pos, isl_ast_loop_unroll);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res).as<schedule_node_band>();
 }
 
-isl::set schedule_constraints::context() const
+schedule_node_band schedule_node_band::member_set_ast_loop_separate(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_schedule_constraints_get_context(get());
+  auto res = isl_schedule_node_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_separate);
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return manage(res).as<schedule_node_band>();
 }
 
-isl::set schedule_constraints::get_context() const
+inline std::ostream &operator<<(std::ostream &os, const schedule_node_band &obj)
 {
-  return context();
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_schedule_node_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::schedule_node_context
+schedule_node_context::schedule_node_context()
+    : schedule_node() {}
+
+schedule_node_context::schedule_node_context(const schedule_node_context &obj)
+    : schedule_node(obj)
+{
+}
+
+schedule_node_context::schedule_node_context(__isl_take isl_schedule_node *ptr)
+    : schedule_node(ptr) {}
+
+schedule_node_context &schedule_node_context::operator=(schedule_node_context obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx schedule_node_context::ctx() const {
+  return isl::ctx(isl_schedule_node_get_ctx(ptr));
 }
 
-isl::union_set schedule_constraints::domain() const
+isl::set schedule_node_context::context() 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_domain(get());
+  auto res = isl_schedule_node_context_get_context(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_set schedule_constraints::get_domain() const
+isl::set schedule_node_context::get_context() const
 {
-  return domain();
+  return context();
 }
 
-isl::union_map schedule_constraints::proximity() const
+inline std::ostream &operator<<(std::ostream &os, const schedule_node_context &obj)
 {
-  if (!ptr)
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_constraints_get_proximity(get());
-  if (!res)
+  char *str = isl_schedule_node_to_str(obj.get());
+  if (!str)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  os << str;
+  free(str);
+  return os;
 }
 
-isl::union_map schedule_constraints::get_proximity() const
+// implementations for isl::schedule_node_domain
+schedule_node_domain::schedule_node_domain()
+    : schedule_node() {}
+
+schedule_node_domain::schedule_node_domain(const schedule_node_domain &obj)
+    : schedule_node(obj)
 {
-  return proximity();
 }
 
-isl::union_map schedule_constraints::validity() const
+schedule_node_domain::schedule_node_domain(__isl_take isl_schedule_node *ptr)
+    : schedule_node(ptr) {}
+
+schedule_node_domain &schedule_node_domain::operator=(schedule_node_domain obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx schedule_node_domain::ctx() const {
+  return isl::ctx(isl_schedule_node_get_ctx(ptr));
+}
+
+isl::union_set schedule_node_domain::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_schedule_constraints_get_validity(get());
+  auto res = isl_schedule_node_domain_get_domain(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map schedule_constraints::get_validity() const
+isl::union_set schedule_node_domain::get_domain() const
 {
-  return validity();
+  return domain();
 }
 
-isl::schedule_constraints schedule_constraints::on_domain(isl::union_set domain)
+inline std::ostream &operator<<(std::ostream &os, const schedule_node_domain &obj)
 {
-  if (domain.is_null())
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = domain.ctx();
+  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_constraints_on_domain(domain.release());
-  if (!res)
+  char *str = isl_schedule_node_to_str(obj.get());
+  if (!str)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  os << str;
+  free(str);
+  return os;
 }
 
-isl::schedule_constraints schedule_constraints::set_coincidence(isl::union_map coincidence) const
+// implementations for isl::schedule_node_expansion
+schedule_node_expansion::schedule_node_expansion()
+    : schedule_node() {}
+
+schedule_node_expansion::schedule_node_expansion(const schedule_node_expansion &obj)
+    : schedule_node(obj)
 {
-  if (!ptr || coincidence.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_constraints_set_coincidence(copy(), coincidence.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
 }
 
-isl::schedule_constraints schedule_constraints::set_conditional_validity(isl::union_map condition, isl::union_map validity) const
+schedule_node_expansion::schedule_node_expansion(__isl_take isl_schedule_node *ptr)
+    : schedule_node(ptr) {}
+
+schedule_node_expansion &schedule_node_expansion::operator=(schedule_node_expansion obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx schedule_node_expansion::ctx() const {
+  return isl::ctx(isl_schedule_node_get_ctx(ptr));
+}
+
+isl::union_pw_multi_aff schedule_node_expansion::contraction() const
 {
-  if (!ptr || condition.is_null() || validity.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_schedule_constraints_set_conditional_validity(copy(), condition.release(), validity.release());
+  auto res = isl_schedule_node_expansion_get_contraction(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::schedule_constraints schedule_constraints::set_context(isl::set context) const
+isl::union_pw_multi_aff schedule_node_expansion::get_contraction() const
 {
-  if (!ptr || context.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_constraints_set_context(copy(), context.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return contraction();
 }
 
-isl::schedule_constraints schedule_constraints::set_proximity(isl::union_map proximity) const
+isl::union_map schedule_node_expansion::expansion() const
 {
-  if (!ptr || proximity.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_schedule_constraints_set_proximity(copy(), proximity.release());
+  auto res = isl_schedule_node_expansion_get_expansion(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::schedule_constraints schedule_constraints::set_validity(isl::union_map validity) const
+isl::union_map schedule_node_expansion::get_expansion() const
 {
-  if (!ptr || validity.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_constraints_set_validity(copy(), validity.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return expansion();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const schedule_constraints &obj)
+inline std::ostream &operator<<(std::ostream &os, const schedule_node_expansion &obj)
 {
   if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_constraints_get_ctx(obj.get());
+  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_schedule_constraints_to_str(obj.get());
+  char *str = isl_schedule_node_to_str(obj.get());
   if (!str)
     exception::throw_last_error(saved_ctx);
   os << str;
@@ -12901,2337 +21381,2170 @@ inline std::ostream &operator<<(std::ostream &os, const schedule_constraints &ob
   return os;
 }
 
-// implementations for isl::schedule_node
-schedule_node manage(__isl_take isl_schedule_node *ptr) {
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return schedule_node(ptr);
+// implementations for isl::schedule_node_extension
+schedule_node_extension::schedule_node_extension()
+    : schedule_node() {}
+
+schedule_node_extension::schedule_node_extension(const schedule_node_extension &obj)
+    : schedule_node(obj)
+{
 }
-schedule_node manage_copy(__isl_keep isl_schedule_node *ptr) {
+
+schedule_node_extension::schedule_node_extension(__isl_take isl_schedule_node *ptr)
+    : schedule_node(ptr) {}
+
+schedule_node_extension &schedule_node_extension::operator=(schedule_node_extension obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx schedule_node_extension::ctx() const {
+  return isl::ctx(isl_schedule_node_get_ctx(ptr));
+}
+
+isl::union_map schedule_node_extension::extension() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_node_get_ctx(ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_schedule_node_copy(ptr);
-  if (!ptr)
+  auto res = isl_schedule_node_extension_get_extension(get());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return schedule_node(ptr);
+  return manage(res);
 }
 
-schedule_node::schedule_node()
-    : ptr(nullptr) {}
+isl::union_map schedule_node_extension::get_extension() const
+{
+  return extension();
+}
 
-schedule_node::schedule_node(const schedule_node &obj)
-    : ptr(nullptr)
+inline std::ostream &operator<<(std::ostream &os, const schedule_node_extension &obj)
 {
-  if (!obj.ptr)
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_node_get_ctx(obj.ptr);
+  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = obj.copy();
-  if (!ptr)
+  char *str = isl_schedule_node_to_str(obj.get());
+  if (!str)
     exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
 }
 
-schedule_node::schedule_node(__isl_take isl_schedule_node *ptr)
-    : ptr(ptr) {}
+// implementations for isl::schedule_node_filter
+schedule_node_filter::schedule_node_filter()
+    : schedule_node() {}
 
-schedule_node &schedule_node::operator=(schedule_node obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+schedule_node_filter::schedule_node_filter(const schedule_node_filter &obj)
+    : schedule_node(obj)
+{
 }
 
-schedule_node::~schedule_node() {
-  if (ptr)
-    isl_schedule_node_free(ptr);
-}
+schedule_node_filter::schedule_node_filter(__isl_take isl_schedule_node *ptr)
+    : schedule_node(ptr) {}
 
-__isl_give isl_schedule_node *schedule_node::copy() const & {
-  return isl_schedule_node_copy(ptr);
+schedule_node_filter &schedule_node_filter::operator=(schedule_node_filter obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
 }
 
-__isl_keep isl_schedule_node *schedule_node::get() const {
-  return ptr;
+isl::ctx schedule_node_filter::ctx() const {
+  return isl::ctx(isl_schedule_node_get_ctx(ptr));
 }
 
-__isl_give isl_schedule_node *schedule_node::release() {
-  isl_schedule_node *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+isl::union_set schedule_node_filter::filter() 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_filter_get_filter(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-bool schedule_node::is_null() const {
-  return ptr == nullptr;
+isl::union_set schedule_node_filter::get_filter() const
+{
+  return filter();
 }
 
-template <typename T, typename>
-bool schedule_node::isa_type(T subtype) const
+inline std::ostream &operator<<(std::ostream &os, const schedule_node_filter &obj)
 {
-  if (is_null())
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return isl_schedule_node_get_type(get()) == subtype;
+  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_schedule_node_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
 }
-template <class T>
-bool schedule_node::isa() const
+
+// implementations for isl::schedule_node_guard
+schedule_node_guard::schedule_node_guard()
+    : schedule_node() {}
+
+schedule_node_guard::schedule_node_guard(const schedule_node_guard &obj)
+    : schedule_node(obj)
 {
-  return isa_type<decltype(T::type)>(T::type);
 }
-template <class T>
-T schedule_node::as() const
-{
- if (!isa<T>())
-    exception::throw_invalid("not an object of the requested subtype", __FILE__, __LINE__);
-  return T(copy());
+
+schedule_node_guard::schedule_node_guard(__isl_take isl_schedule_node *ptr)
+    : schedule_node(ptr) {}
+
+schedule_node_guard &schedule_node_guard::operator=(schedule_node_guard obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
 }
 
-isl::ctx schedule_node::ctx() const {
+isl::ctx schedule_node_guard::ctx() const {
   return isl::ctx(isl_schedule_node_get_ctx(ptr));
 }
 
-isl::schedule_node schedule_node::ancestor(int generation) const
+isl::set schedule_node_guard::guard() 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_ancestor(copy(), generation);
+  auto res = isl_schedule_node_guard_get_guard(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::schedule_node schedule_node::child(int pos) const
+isl::set schedule_node_guard::get_guard() 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_child(copy(), pos);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return guard();
 }
 
-bool schedule_node::every_descendant(const std::function<bool(isl::schedule_node)> &test) const
+inline std::ostream &operator<<(std::ostream &os, const schedule_node_guard &obj)
 {
-  if (!ptr)
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  struct test_data {
-    std::function<bool(isl::schedule_node)> func;
-    std::exception_ptr eptr;
-  } test_data = { test };
-  auto test_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_bool {
-    auto *data = static_cast<struct test_data *>(arg_1);
-    ISL_CPP_TRY {
-      auto ret = (data->func)(manage_copy(arg_0));
-      return ret ? isl_bool_true : isl_bool_false;
-    } ISL_CPP_CATCH_ALL {
-      data->eptr = std::current_exception();
-      return isl_bool_error;
-    }
-  };
-  auto res = isl_schedule_node_every_descendant(get(), test_lambda, &test_data);
-  if (test_data.eptr)
-    std::rethrow_exception(test_data.eptr);
-  if (res < 0)
+  char *str = isl_schedule_node_to_str(obj.get());
+  if (!str)
     exception::throw_last_error(saved_ctx);
-  return res;
+  os << str;
+  free(str);
+  return os;
 }
 
-isl::schedule_node schedule_node::first_child() const
+// implementations for isl::schedule_node_leaf
+schedule_node_leaf::schedule_node_leaf()
+    : schedule_node() {}
+
+schedule_node_leaf::schedule_node_leaf(const schedule_node_leaf &obj)
+    : schedule_node(obj)
 {
-  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_first_child(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
 }
 
-void schedule_node::foreach_ancestor_top_down(const std::function<void(isl::schedule_node)> &fn) const
+schedule_node_leaf::schedule_node_leaf(__isl_take isl_schedule_node *ptr)
+    : schedule_node(ptr) {}
+
+schedule_node_leaf &schedule_node_leaf::operator=(schedule_node_leaf obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx schedule_node_leaf::ctx() const {
+  return isl::ctx(isl_schedule_node_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const schedule_node_leaf &obj)
 {
-  if (!ptr)
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  struct fn_data {
-    std::function<void(isl::schedule_node)> func;
-    std::exception_ptr eptr;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_stat {
-    auto *data = static_cast<struct fn_data *>(arg_1);
-    ISL_CPP_TRY {
-      (data->func)(manage_copy(arg_0));
-      return isl_stat_ok;
-    } ISL_CPP_CATCH_ALL {
-      data->eptr = std::current_exception();
-      return isl_stat_error;
-    }
-  };
-  auto res = isl_schedule_node_foreach_ancestor_top_down(get(), fn_lambda, &fn_data);
-  if (fn_data.eptr)
-    std::rethrow_exception(fn_data.eptr);
-  if (res < 0)
+  char *str = isl_schedule_node_to_str(obj.get());
+  if (!str)
     exception::throw_last_error(saved_ctx);
-  return;
+  os << str;
+  free(str);
+  return os;
 }
 
-void schedule_node::foreach_descendant_top_down(const std::function<bool(isl::schedule_node)> &fn) const
+// implementations for isl::schedule_node_mark
+schedule_node_mark::schedule_node_mark()
+    : schedule_node() {}
+
+schedule_node_mark::schedule_node_mark(const schedule_node_mark &obj)
+    : schedule_node(obj)
 {
-  if (!ptr)
+}
+
+schedule_node_mark::schedule_node_mark(__isl_take isl_schedule_node *ptr)
+    : schedule_node(ptr) {}
+
+schedule_node_mark &schedule_node_mark::operator=(schedule_node_mark obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx schedule_node_mark::ctx() const {
+  return isl::ctx(isl_schedule_node_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const schedule_node_mark &obj)
+{
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  struct fn_data {
-    std::function<bool(isl::schedule_node)> func;
-    std::exception_ptr eptr;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_bool {
-    auto *data = static_cast<struct fn_data *>(arg_1);
-    ISL_CPP_TRY {
-      auto ret = (data->func)(manage_copy(arg_0));
-      return ret ? isl_bool_true : isl_bool_false;
-    } ISL_CPP_CATCH_ALL {
-      data->eptr = std::current_exception();
-      return isl_bool_error;
-    }
-  };
-  auto res = isl_schedule_node_foreach_descendant_top_down(get(), fn_lambda, &fn_data);
-  if (fn_data.eptr)
-    std::rethrow_exception(fn_data.eptr);
-  if (res < 0)
+  char *str = isl_schedule_node_to_str(obj.get());
+  if (!str)
     exception::throw_last_error(saved_ctx);
-  return;
+  os << str;
+  free(str);
+  return os;
 }
 
-isl::schedule_node schedule_node::from_domain(isl::union_set domain)
+// implementations for isl::schedule_node_sequence
+schedule_node_sequence::schedule_node_sequence()
+    : schedule_node() {}
+
+schedule_node_sequence::schedule_node_sequence(const schedule_node_sequence &obj)
+    : schedule_node(obj)
 {
-  if (domain.is_null())
+}
+
+schedule_node_sequence::schedule_node_sequence(__isl_take isl_schedule_node *ptr)
+    : schedule_node(ptr) {}
+
+schedule_node_sequence &schedule_node_sequence::operator=(schedule_node_sequence obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx schedule_node_sequence::ctx() const {
+  return isl::ctx(isl_schedule_node_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const schedule_node_sequence &obj)
+{
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = domain.ctx();
+  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_node_from_domain(domain.release());
-  if (!res)
+  char *str = isl_schedule_node_to_str(obj.get());
+  if (!str)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  os << str;
+  free(str);
+  return os;
 }
 
-isl::schedule_node schedule_node::from_extension(isl::union_map extension)
+// implementations for isl::schedule_node_set
+schedule_node_set::schedule_node_set()
+    : schedule_node() {}
+
+schedule_node_set::schedule_node_set(const schedule_node_set &obj)
+    : schedule_node(obj)
 {
-  if (extension.is_null())
+}
+
+schedule_node_set::schedule_node_set(__isl_take isl_schedule_node *ptr)
+    : schedule_node(ptr) {}
+
+schedule_node_set &schedule_node_set::operator=(schedule_node_set obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+isl::ctx schedule_node_set::ctx() const {
+  return isl::ctx(isl_schedule_node_get_ctx(ptr));
+}
+
+inline std::ostream &operator<<(std::ostream &os, const schedule_node_set &obj)
+{
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = extension.ctx();
+  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_node_from_extension(extension.release());
-  if (!res)
+  char *str = isl_schedule_node_to_str(obj.get());
+  if (!str)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  os << str;
+  free(str);
+  return os;
 }
 
-unsigned schedule_node::ancestor_child_position(const isl::schedule_node &ancestor) const
-{
-  if (!ptr || ancestor.is_null())
+// implementations for isl::set
+set manage(__isl_take isl_set *ptr) {
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  return set(ptr);
+}
+set manage_copy(__isl_keep isl_set *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_set_get_ctx(ptr);
   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)
+  ptr = isl_set_copy(ptr);
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return set(ptr);
 }
 
-unsigned schedule_node::get_ancestor_child_position(const isl::schedule_node &ancestor) const
-{
-  return ancestor_child_position(ancestor);
-}
+set::set()
+    : ptr(nullptr) {}
 
-unsigned schedule_node::child_position() const
+set::set(const set &obj)
+    : ptr(nullptr)
 {
-  if (!ptr)
+  if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_set_get_ctx(obj.ptr);
   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)
+  ptr = obj.copy();
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return res;
 }
 
-unsigned schedule_node::get_child_position() const
-{
-  return child_position();
-}
+set::set(__isl_take isl_set *ptr)
+    : ptr(ptr) {}
 
-isl::multi_union_pw_aff schedule_node::prefix_schedule_multi_union_pw_aff() const
+set::set(isl::basic_set bset)
 {
-  if (!ptr)
+  if (bset.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = bset.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());
+  auto res = isl_set_from_basic_set(bset.release());
   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();
+  ptr = res;
 }
 
-isl::union_map schedule_node::prefix_schedule_union_map() const
+set::set(isl::point pnt)
 {
-  if (!ptr)
+  if (pnt.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = pnt.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());
+  auto res = isl_set_from_point(pnt.release());
   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();
+  ptr = res;
 }
 
-isl::union_pw_multi_aff schedule_node::prefix_schedule_union_pw_multi_aff() const
+set::set(isl::ctx ctx, const std::string &str)
 {
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  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());
+  auto res = isl_set_read_from_str(ctx.release(), str.c_str());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  ptr = res;
 }
 
-isl::union_pw_multi_aff schedule_node::get_prefix_schedule_union_pw_multi_aff() const
-{
-  return prefix_schedule_union_pw_multi_aff();
+set &set::operator=(set obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
 }
 
-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);
+set::~set() {
+  if (ptr)
+    isl_set_free(ptr);
 }
 
-isl::schedule schedule_node::get_schedule() const
-{
-  return schedule();
+__isl_give isl_set *set::copy() const & {
+  return isl_set_copy(ptr);
 }
 
-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_keep isl_set *set::get() const {
+  return ptr;
 }
 
-isl::schedule_node schedule_node::get_shared_ancestor(const isl::schedule_node &node2) const
-{
-  return shared_ancestor(node2);
+__isl_give isl_set *set::release() {
+  isl_set *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
 }
 
-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;
+bool set::is_null() const {
+  return ptr == nullptr;
 }
 
-unsigned schedule_node::get_tree_depth() const
-{
-  return tree_depth();
+isl::ctx set::ctx() const {
+  return isl::ctx(isl_set_get_ctx(ptr));
 }
 
-isl::schedule_node schedule_node::graft_after(isl::schedule_node graft) const
+isl::basic_set set::affine_hull() const
 {
-  if (!ptr || graft.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_schedule_node_graft_after(copy(), graft.release());
+  auto res = isl_set_affine_hull(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::schedule_node schedule_node::graft_before(isl::schedule_node graft) const
+isl::set set::apply(isl::map map) const
 {
-  if (!ptr || graft.is_null())
+  if (!ptr || map.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_graft_before(copy(), graft.release());
+  auto res = isl_set_apply(copy(), map.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool schedule_node::has_children() const
+isl::union_set set::apply(const isl::union_map &umap) 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_has_children(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::union_set(*this).apply(umap);
 }
 
-bool schedule_node::has_next_sibling() const
+isl::set set::apply(const isl::basic_map &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_has_next_sibling(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return this->apply(isl::map(map));
 }
 
-bool schedule_node::has_parent() const
+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_schedule_node_has_parent(get());
-  if (res < 0)
+  auto res = isl_set_as_pw_multi_aff(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-bool schedule_node::has_previous_sibling() const
+isl::set 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_schedule_node_has_previous_sibling(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::union_set(*this).as_set();
 }
 
-isl::schedule_node schedule_node::insert_context(isl::set context) const
+isl::set set::bind(isl::multi_id tuple) const
 {
-  if (!ptr || context.is_null())
+  if (!ptr || tuple.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_insert_context(copy(), context.release());
+  auto res = isl_set_bind(copy(), tuple.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::schedule_node schedule_node::insert_filter(isl::union_set filter) const
+isl::set set::coalesce() const
 {
-  if (!ptr || filter.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_schedule_node_insert_filter(copy(), filter.release());
+  auto res = isl_set_coalesce(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::schedule_node schedule_node::insert_guard(isl::set context) const
+isl::set set::complement() const
 {
-  if (!ptr || context.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_schedule_node_insert_guard(copy(), context.release());
+  auto res = isl_set_complement(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::schedule_node schedule_node::insert_mark(isl::id mark) const
+isl::union_set set::compute_divs() const
 {
-  if (!ptr || mark.is_null())
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).compute_divs();
+}
+
+isl::set set::detect_equalities() 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_insert_mark(copy(), mark.release());
+  auto res = isl_set_detect_equalities(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::schedule_node schedule_node::insert_mark(const std::string &mark) const
+isl::val set::dim_max_val(int pos) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->insert_mark(isl::id(ctx(), mark));
-}
-
-isl::schedule_node schedule_node::insert_partial_schedule(isl::multi_union_pw_aff schedule) const
-{
-  if (!ptr || schedule.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_insert_partial_schedule(copy(), schedule.release());
+  auto res = isl_set_dim_max_val(copy(), pos);
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::schedule_node schedule_node::insert_sequence(isl::union_set_list filters) const
+isl::val set::dim_min_val(int pos) const
 {
-  if (!ptr || filters.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_schedule_node_insert_sequence(copy(), filters.release());
+  auto res = isl_set_dim_min_val(copy(), pos);
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::schedule_node schedule_node::insert_set(isl::union_set_list filters) const
+isl::set set::empty(isl::space space)
 {
-  if (!ptr || filters.is_null())
+  if (space.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = space.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_node_insert_set(copy(), filters.release());
+  auto res = isl_set_empty(space.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool schedule_node::is_equal(const isl::schedule_node &node2) const
+bool set::every_set(const std::function<bool(isl::set)> &test) const
 {
-  if (!ptr || node2.is_null())
+  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)
     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_is_equal(get(), node2.get());
-  if (res < 0)
+  auto res = isl_set_flatten(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-bool schedule_node::is_subtree_anchored() const
+void set::foreach_basic_set(const std::function<void(isl::basic_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_schedule_node_is_subtree_anchored(get());
+  struct fn_data {
+    std::function<void(isl::basic_set)> func;
+    std::exception_ptr eptr;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_basic_set *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_set_foreach_basic_set(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 res;
+  return;
 }
 
-isl::schedule_node schedule_node::map_descendant_bottom_up(const std::function<isl::schedule_node(isl::schedule_node)> &fn) const
+void set::foreach_point(const std::function<void(isl::point)> &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<isl::schedule_node(isl::schedule_node)> func;
+    std::function<void(isl::point)> func;
     std::exception_ptr eptr;
   } fn_data = { fn };
-  auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_schedule_node * {
+  auto fn_lambda = [](isl_point *arg_0, void *arg_1) -> isl_stat {
     auto *data = static_cast<struct fn_data *>(arg_1);
     ISL_CPP_TRY {
-      auto ret = (data->func)(manage(arg_0));
-      return ret.release();
+      (data->func)(manage(arg_0));
+      return isl_stat_ok;
     } ISL_CPP_CATCH_ALL {
       data->eptr = std::current_exception();
-      return NULL;
+      return isl_stat_error;
     }
   };
-  auto res = isl_schedule_node_map_descendant_bottom_up(copy(), fn_lambda, &fn_data);
+  auto res = isl_set_foreach_point(get(), fn_lambda, &fn_data);
   if (fn_data.eptr)
     std::rethrow_exception(fn_data.eptr);
-  if (!res)
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return;
 }
 
-unsigned schedule_node::n_children() 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_schedule_node_n_children(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::union_set(*this).foreach_set(fn);
 }
 
-isl::schedule_node schedule_node::next_sibling() const
+isl::set set::gist(isl::set context) const
 {
-  if (!ptr)
+  if (!ptr || context.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_next_sibling(copy());
+  auto res = isl_set_gist(copy(), context.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::schedule_node schedule_node::order_after(isl::union_set filter) const
+isl::union_set set::gist(const isl::union_set &context) const
 {
-  if (!ptr || filter.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_schedule_node_order_after(copy(), filter.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_set(*this).gist(context);
 }
 
-isl::schedule_node schedule_node::order_before(isl::union_set filter) const
+isl::set set::gist(const isl::basic_set &context) const
 {
-  if (!ptr || filter.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_schedule_node_order_before(copy(), filter.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->gist(isl::set(context));
 }
 
-isl::schedule_node schedule_node::parent() const
+isl::set set::gist(const isl::point &context) 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_parent(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->gist(isl::set(context));
 }
 
-isl::schedule_node schedule_node::previous_sibling() const
+isl::union_set set::gist_params(const isl::set &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_schedule_node_previous_sibling(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_set(*this).gist_params(set);
 }
 
-isl::schedule_node schedule_node::root() const
+isl::map set::identity() 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_root(copy());
+  auto res = isl_set_identity(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const schedule_node &obj)
-{
-  if (!obj.get())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_schedule_node_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
-}
-
-// implementations for isl::schedule_node_band
-schedule_node_band::schedule_node_band()
-    : schedule_node() {}
-
-schedule_node_band::schedule_node_band(const schedule_node_band &obj)
-    : schedule_node(obj)
-{
-}
-
-schedule_node_band::schedule_node_band(__isl_take isl_schedule_node *ptr)
-    : schedule_node(ptr) {}
-
-schedule_node_band &schedule_node_band::operator=(schedule_node_band obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx schedule_node_band::ctx() const {
-  return isl::ctx(isl_schedule_node_get_ctx(ptr));
-}
-
-isl::union_set schedule_node_band::ast_build_options() const
+isl::pw_aff set::indicator_function() 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_ast_build_options(get());
+  auto res = isl_set_indicator_function(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_set schedule_node_band::get_ast_build_options() const
-{
-  return ast_build_options();
-}
-
-isl::set schedule_node_band::ast_isolate_option() const
+isl::map set::insert_domain(isl::space domain) const
 {
-  if (!ptr)
+  if (!ptr || domain.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_band_get_ast_isolate_option(get());
+  auto res = isl_set_insert_domain(copy(), domain.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set schedule_node_band::get_ast_isolate_option() const
-{
-  return ast_isolate_option();
-}
-
-isl::multi_union_pw_aff schedule_node_band::partial_schedule() const
+isl::set set::intersect(isl::set set2) const
 {
-  if (!ptr)
+  if (!ptr || set2.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_band_get_partial_schedule(get());
+  auto res = isl_set_intersect(copy(), set2.release());
   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
+isl::union_set set::intersect(const isl::union_set &uset2) 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();
+  return isl::union_set(*this).intersect(uset2);
 }
 
-bool schedule_node_band::member_get_coincident(int pos) const
+isl::set set::intersect(const isl::basic_set &set2) 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_member_get_coincident(get(), pos);
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return this->intersect(isl::set(set2));
 }
 
-schedule_node_band schedule_node_band::member_set_coincident(int pos, int coincident) const
+isl::set set::intersect(const isl::point &set2) 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_member_set_coincident(copy(), pos, coincident);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res).as<schedule_node_band>();
+  return this->intersect(isl::set(set2));
 }
 
-schedule_node_band schedule_node_band::mod(isl::multi_val mv) const
+isl::set set::intersect_params(isl::set params) const
 {
-  if (!ptr || mv.is_null())
+  if (!ptr || params.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_band_mod(copy(), mv.release());
+  auto res = isl_set_intersect_params(copy(), params.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  return manage(res).as<schedule_node_band>();
+  return manage(res);
 }
 
-unsigned schedule_node_band::n_member() const
+bool set::involves_locals() 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_n_member(get());
+  auto res = isl_set_involves_locals(get());
   if (res < 0)
     exception::throw_last_error(saved_ctx);
   return res;
 }
 
-schedule_node_band schedule_node_band::scale(isl::multi_val mv) const
+bool set::is_disjoint(const isl::set &set2) const
 {
-  if (!ptr || mv.is_null())
+  if (!ptr || set2.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_band_scale(copy(), mv.release());
-  if (!res)
+  auto res = isl_set_is_disjoint(get(), set2.get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res).as<schedule_node_band>();
+  return res;
 }
 
-schedule_node_band schedule_node_band::scale_down(isl::multi_val mv) const
+bool set::is_disjoint(const isl::union_set &uset2) const
 {
-  if (!ptr || mv.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_schedule_node_band_scale_down(copy(), mv.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res).as<schedule_node_band>();
+  return isl::union_set(*this).is_disjoint(uset2);
 }
 
-schedule_node_band schedule_node_band::set_ast_build_options(isl::union_set options) const
+bool set::is_disjoint(const isl::basic_set &set2) const
 {
-  if (!ptr || options.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_schedule_node_band_set_ast_build_options(copy(), options.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res).as<schedule_node_band>();
+  return this->is_disjoint(isl::set(set2));
 }
 
-schedule_node_band schedule_node_band::set_permutable(int permutable) const
+bool set::is_disjoint(const isl::point &set2) 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_set_permutable(copy(), permutable);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res).as<schedule_node_band>();
+  return this->is_disjoint(isl::set(set2));
 }
 
-schedule_node_band schedule_node_band::shift(isl::multi_union_pw_aff shift) const
+bool set::is_empty() const
 {
-  if (!ptr || shift.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_schedule_node_band_shift(copy(), shift.release());
-  if (!res)
+  auto res = isl_set_is_empty(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res).as<schedule_node_band>();
+  return res;
 }
 
-schedule_node_band schedule_node_band::split(int pos) const
+bool set::is_equal(const isl::set &set2) const
 {
-  if (!ptr)
+  if (!ptr || set2.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_band_split(copy(), pos);
-  if (!res)
+  auto res = isl_set_is_equal(get(), set2.get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res).as<schedule_node_band>();
+  return res;
 }
 
-schedule_node_band schedule_node_band::tile(isl::multi_val sizes) const
+bool set::is_equal(const isl::union_set &uset2) const
 {
-  if (!ptr || sizes.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_schedule_node_band_tile(copy(), sizes.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res).as<schedule_node_band>();
+  return isl::union_set(*this).is_equal(uset2);
 }
 
-schedule_node_band schedule_node_band::member_set_ast_loop_default(int pos) const
+bool set::is_equal(const isl::basic_set &set2) 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_member_set_ast_loop_type(copy(), pos, isl_ast_loop_default);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res).as<schedule_node_band>();
+  return this->is_equal(isl::set(set2));
 }
 
-schedule_node_band schedule_node_band::member_set_ast_loop_atomic(int pos) const
+bool set::is_equal(const isl::point &set2) 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_member_set_ast_loop_type(copy(), pos, isl_ast_loop_atomic);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res).as<schedule_node_band>();
+  return this->is_equal(isl::set(set2));
 }
 
-schedule_node_band schedule_node_band::member_set_ast_loop_unroll(int pos) const
+bool set::is_singleton() 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_member_set_ast_loop_type(copy(), pos, isl_ast_loop_unroll);
-  if (!res)
+  auto res = isl_set_is_singleton(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res).as<schedule_node_band>();
+  return res;
 }
 
-schedule_node_band schedule_node_band::member_set_ast_loop_separate(int pos) const
+bool set::is_strict_subset(const isl::set &set2) const
 {
-  if (!ptr)
+  if (!ptr || set2.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_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_separate);
-  if (!res)
+  auto res = isl_set_is_strict_subset(get(), set2.get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res).as<schedule_node_band>();
+  return res;
 }
 
-inline std::ostream &operator<<(std::ostream &os, const schedule_node_band &obj)
+bool set::is_strict_subset(const isl::union_set &uset2) const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_schedule_node_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return isl::union_set(*this).is_strict_subset(uset2);
 }
 
-// implementations for isl::schedule_node_context
-schedule_node_context::schedule_node_context()
-    : schedule_node() {}
-
-schedule_node_context::schedule_node_context(const schedule_node_context &obj)
-    : schedule_node(obj)
+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));
 }
 
-schedule_node_context::schedule_node_context(__isl_take isl_schedule_node *ptr)
-    : schedule_node(ptr) {}
-
-schedule_node_context &schedule_node_context::operator=(schedule_node_context obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx schedule_node_context::ctx() const {
-  return isl::ctx(isl_schedule_node_get_ctx(ptr));
+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));
 }
 
-isl::set schedule_node_context::context() const
+bool set::is_subset(const isl::set &set2) const
 {
-  if (!ptr)
+  if (!ptr || set2.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_context_get_context(get());
-  if (!res)
+  auto res = isl_set_is_subset(get(), set2.get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::set schedule_node_context::get_context() const
+bool set::is_subset(const isl::union_set &uset2) const
 {
-  return context();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).is_subset(uset2);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const schedule_node_context &obj)
+bool set::is_subset(const isl::basic_set &set2) const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_schedule_node_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return this->is_subset(isl::set(set2));
 }
 
-// implementations for isl::schedule_node_domain
-schedule_node_domain::schedule_node_domain()
-    : schedule_node() {}
-
-schedule_node_domain::schedule_node_domain(const schedule_node_domain &obj)
-    : schedule_node(obj)
+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));
 }
 
-schedule_node_domain::schedule_node_domain(__isl_take isl_schedule_node *ptr)
-    : schedule_node(ptr) {}
-
-schedule_node_domain &schedule_node_domain::operator=(schedule_node_domain obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx schedule_node_domain::ctx() const {
-  return isl::ctx(isl_schedule_node_get_ctx(ptr));
-}
-
-isl::union_set schedule_node_domain::domain() const
+bool set::is_wrapping() 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_domain_get_domain(get());
-  if (!res)
+  auto res = isl_set_is_wrapping(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::union_set schedule_node_domain::get_domain() const
+bool set::isa_set() const
 {
-  return domain();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).isa_set();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const schedule_node_domain &obj)
+isl::set set::lexmax() const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_schedule_node_to_str(obj.get());
-  if (!str)
+  auto res = isl_set_lexmax(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
-}
-
-// implementations for isl::schedule_node_expansion
-schedule_node_expansion::schedule_node_expansion()
-    : schedule_node() {}
-
-schedule_node_expansion::schedule_node_expansion(const schedule_node_expansion &obj)
-    : schedule_node(obj)
-{
-}
-
-schedule_node_expansion::schedule_node_expansion(__isl_take isl_schedule_node *ptr)
-    : schedule_node(ptr) {}
-
-schedule_node_expansion &schedule_node_expansion::operator=(schedule_node_expansion obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx schedule_node_expansion::ctx() const {
-  return isl::ctx(isl_schedule_node_get_ctx(ptr));
+  return manage(res);
 }
 
-isl::union_pw_multi_aff schedule_node_expansion::contraction() const
+isl::pw_multi_aff set::lexmax_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_expansion_get_contraction(get());
+  auto res = isl_set_lexmax_pw_multi_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_pw_multi_aff schedule_node_expansion::get_contraction() const
-{
-  return contraction();
-}
-
-isl::union_map schedule_node_expansion::expansion() const
+isl::set set::lexmin() 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_expansion_get_expansion(get());
+  auto res = isl_set_lexmin(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map schedule_node_expansion::get_expansion() const
+isl::pw_multi_aff set::lexmin_pw_multi_aff() const
 {
-  return expansion();
+  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_lexmin_pw_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const schedule_node_expansion &obj)
+isl::set set::lower_bound(isl::multi_pw_aff lower) const
 {
-  if (!obj.get())
+  if (!ptr || lower.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_schedule_node_to_str(obj.get());
-  if (!str)
+  auto res = isl_set_lower_bound_multi_pw_aff(copy(), lower.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::schedule_node_extension
-schedule_node_extension::schedule_node_extension()
-    : schedule_node() {}
-
-schedule_node_extension::schedule_node_extension(const schedule_node_extension &obj)
-    : schedule_node(obj)
+isl::set set::lower_bound(isl::multi_val lower) const
 {
+  if (!ptr || lower.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_lower_bound_multi_val(copy(), lower.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-schedule_node_extension::schedule_node_extension(__isl_take isl_schedule_node *ptr)
-    : schedule_node(ptr) {}
-
-schedule_node_extension &schedule_node_extension::operator=(schedule_node_extension obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx schedule_node_extension::ctx() const {
-  return isl::ctx(isl_schedule_node_get_ctx(ptr));
-}
-
-isl::union_map schedule_node_extension::extension() const
+isl::multi_pw_aff set::max_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_schedule_node_extension_get_extension(get());
+  auto res = isl_set_max_multi_pw_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map schedule_node_extension::get_extension() const
-{
-  return extension();
-}
-
-inline std::ostream &operator<<(std::ostream &os, const schedule_node_extension &obj)
+isl::val set::max_val(const isl::aff &obj) const
 {
-  if (!obj.get())
+  if (!ptr || obj.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_schedule_node_to_str(obj.get());
-  if (!str)
+  auto res = isl_set_max_val(get(), obj.get());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::schedule_node_filter
-schedule_node_filter::schedule_node_filter()
-    : schedule_node() {}
-
-schedule_node_filter::schedule_node_filter(const schedule_node_filter &obj)
-    : schedule_node(obj)
+isl::multi_pw_aff set::min_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_set_min_multi_pw_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-schedule_node_filter::schedule_node_filter(__isl_take isl_schedule_node *ptr)
-    : schedule_node(ptr) {}
-
-schedule_node_filter &schedule_node_filter::operator=(schedule_node_filter obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx schedule_node_filter::ctx() const {
-  return isl::ctx(isl_schedule_node_get_ctx(ptr));
-}
-
-isl::union_set schedule_node_filter::filter() const
+isl::val set::min_val(const isl::aff &obj) const
 {
-  if (!ptr)
+  if (!ptr || obj.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_filter_get_filter(get());
+  auto res = isl_set_min_val(get(), obj.get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_set schedule_node_filter::get_filter() const
+isl::set set::params() const
 {
-  return filter();
+  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_params(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const schedule_node_filter &obj)
+isl::multi_val set::plain_multi_val_if_fixed() const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_schedule_node_to_str(obj.get());
-  if (!str)
+  auto res = isl_set_get_plain_multi_val_if_fixed(get());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::schedule_node_guard
-schedule_node_guard::schedule_node_guard()
-    : schedule_node() {}
-
-schedule_node_guard::schedule_node_guard(const schedule_node_guard &obj)
-    : schedule_node(obj)
+isl::multi_val set::get_plain_multi_val_if_fixed() const
 {
+  return plain_multi_val_if_fixed();
 }
 
-schedule_node_guard::schedule_node_guard(__isl_take isl_schedule_node *ptr)
-    : schedule_node(ptr) {}
-
-schedule_node_guard &schedule_node_guard::operator=(schedule_node_guard obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx schedule_node_guard::ctx() const {
-  return isl::ctx(isl_schedule_node_get_ctx(ptr));
-}
-
-isl::set schedule_node_guard::guard() const
+isl::basic_set set::polyhedral_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_schedule_node_guard_get_guard(get());
+  auto res = isl_set_polyhedral_hull(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set schedule_node_guard::get_guard() const
-{
-  return guard();
-}
-
-inline std::ostream &operator<<(std::ostream &os, const schedule_node_guard &obj)
+isl::set set::preimage(isl::multi_aff ma) const
 {
-  if (!obj.get())
+  if (!ptr || ma.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_schedule_node_to_str(obj.get());
-  if (!str)
+  auto res = isl_set_preimage_multi_aff(copy(), ma.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::schedule_node_leaf
-schedule_node_leaf::schedule_node_leaf()
-    : schedule_node() {}
-
-schedule_node_leaf::schedule_node_leaf(const schedule_node_leaf &obj)
-    : schedule_node(obj)
+isl::set set::preimage(isl::multi_pw_aff mpa) const
 {
+  if (!ptr || mpa.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_preimage_multi_pw_aff(copy(), mpa.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-schedule_node_leaf::schedule_node_leaf(__isl_take isl_schedule_node *ptr)
-    : schedule_node(ptr) {}
-
-schedule_node_leaf &schedule_node_leaf::operator=(schedule_node_leaf obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx schedule_node_leaf::ctx() const {
-  return isl::ctx(isl_schedule_node_get_ctx(ptr));
-}
-
-inline std::ostream &operator<<(std::ostream &os, const schedule_node_leaf &obj)
+isl::set set::preimage(isl::pw_multi_aff pma) const
 {
-  if (!obj.get())
+  if (!ptr || pma.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_schedule_node_to_str(obj.get());
-  if (!str)
+  auto res = isl_set_preimage_pw_multi_aff(copy(), pma.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::schedule_node_mark
-schedule_node_mark::schedule_node_mark()
-    : schedule_node() {}
-
-schedule_node_mark::schedule_node_mark(const schedule_node_mark &obj)
-    : schedule_node(obj)
+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);
 }
 
-schedule_node_mark::schedule_node_mark(__isl_take isl_schedule_node *ptr)
-    : schedule_node(ptr) {}
-
-schedule_node_mark &schedule_node_mark::operator=(schedule_node_mark obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx schedule_node_mark::ctx() const {
-  return isl::ctx(isl_schedule_node_get_ctx(ptr));
-}
-
-inline std::ostream &operator<<(std::ostream &os, const schedule_node_mark &obj)
+isl::set set::product(isl::set set2) const
 {
-  if (!obj.get())
+  if (!ptr || set2.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_schedule_node_to_str(obj.get());
-  if (!str)
+  auto res = isl_set_product(copy(), set2.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::schedule_node_sequence
-schedule_node_sequence::schedule_node_sequence()
-    : schedule_node() {}
-
-schedule_node_sequence::schedule_node_sequence(const schedule_node_sequence &obj)
-    : schedule_node(obj)
+isl::set set::project_out_all_params() 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_project_out_all_params(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-schedule_node_sequence::schedule_node_sequence(__isl_take isl_schedule_node *ptr)
-    : schedule_node(ptr) {}
-
-schedule_node_sequence &schedule_node_sequence::operator=(schedule_node_sequence obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx schedule_node_sequence::ctx() const {
-  return isl::ctx(isl_schedule_node_get_ctx(ptr));
-}
-
-inline std::ostream &operator<<(std::ostream &os, const schedule_node_sequence &obj)
+isl::set set::project_out_param(isl::id id) const
 {
-  if (!obj.get())
+  if (!ptr || id.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_schedule_node_to_str(obj.get());
-  if (!str)
+  auto res = isl_set_project_out_param_id(copy(), id.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::schedule_node_set
-schedule_node_set::schedule_node_set()
-    : schedule_node() {}
-
-schedule_node_set::schedule_node_set(const schedule_node_set &obj)
-    : schedule_node(obj)
+isl::set 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));
 }
 
-schedule_node_set::schedule_node_set(__isl_take isl_schedule_node *ptr)
-    : schedule_node(ptr) {}
-
-schedule_node_set &schedule_node_set::operator=(schedule_node_set obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-isl::ctx schedule_node_set::ctx() const {
-  return isl::ctx(isl_schedule_node_get_ctx(ptr));
-}
-
-inline std::ostream &operator<<(std::ostream &os, const schedule_node_set &obj)
+isl::set set::project_out_param(isl::id_list list) const
 {
-  if (!obj.get())
+  if (!ptr || list.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_schedule_node_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_schedule_node_to_str(obj.get());
-  if (!str)
+  auto res = isl_set_project_out_param_id_list(copy(), list.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::set
-set manage(__isl_take isl_set *ptr) {
-  if (!ptr)
+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__);
-  return set(ptr);
+  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);
 }
-set manage_copy(__isl_keep isl_set *ptr) {
+
+isl::basic_set set::sample() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_set_get_ctx(ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_set_copy(ptr);
-  if (!ptr)
+  auto res = isl_set_sample(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return set(ptr);
+  return manage(res);
 }
 
-set::set()
-    : ptr(nullptr) {}
-
-set::set(const set &obj)
-    : ptr(nullptr)
+isl::point set::sample_point() const
 {
-  if (!obj.ptr)
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_set_get_ctx(obj.ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = obj.copy();
-  if (!ptr)
+  auto res = isl_set_sample_point(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-set::set(__isl_take isl_set *ptr)
-    : ptr(ptr) {}
-
-set::set(isl::basic_set bset)
+isl::fixed_box set::simple_fixed_box_hull() const
 {
-  if (bset.is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = bset.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_set_from_basic_set(bset.release());
+  auto res = isl_set_get_simple_fixed_box_hull(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-set::set(isl::point pnt)
+isl::fixed_box set::get_simple_fixed_box_hull() const
 {
-  if (pnt.is_null())
+  return simple_fixed_box_hull();
+}
+
+isl::space set::space() const
+{
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = pnt.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_set_from_point(pnt.release());
+  auto res = isl_set_get_space(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-set::set(isl::ctx ctx, const std::string &str)
+isl::space set::get_space() const
 {
-  auto saved_ctx = ctx;
+  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_read_from_str(ctx.release(), str.c_str());
+  auto res = isl_set_get_stride(get(), pos);
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-set &set::operator=(set obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+  return manage(res);
 }
 
-set::~set() {
-  if (ptr)
-    isl_set_free(ptr);
+isl::val set::get_stride(int pos) const
+{
+  return stride(pos);
 }
 
-__isl_give isl_set *set::copy() const & {
-  return isl_set_copy(ptr);
+isl::set set::subtract(isl::set set2) const
+{
+  if (!ptr || set2.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_subtract(copy(), set2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-__isl_keep isl_set *set::get() const {
-  return ptr;
+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_give isl_set *set::release() {
-  isl_set *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+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));
 }
 
-bool set::is_null() const {
-  return ptr == nullptr;
+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::ctx set::ctx() const {
-  return isl::ctx(isl_set_get_ctx(ptr));
+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::basic_set set::affine_hull() const
+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_affine_hull(copy());
+  auto res = isl_set_to_union_set(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::apply(isl::map map) const
+isl::map set::translation() const
 {
-  if (!ptr || map.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_set_apply(copy(), map.release());
+  auto res = isl_set_translation(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::bind(isl::multi_id tuple) const
+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())
     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_bind(copy(), tuple.release());
+  auto res = isl_set_unbind_params(copy(), tuple.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::coalesce() const
+isl::map set::unbind_params_insert_domain(isl::multi_id domain) const
 {
-  if (!ptr)
+  if (!ptr || domain.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_coalesce(copy());
+  auto res = isl_set_unbind_params_insert_domain(copy(), domain.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::complement() const
+isl::set set::unite(isl::set set2) const
 {
-  if (!ptr)
+  if (!ptr || set2.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_complement(copy());
+  auto res = isl_set_union(copy(), set2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::detect_equalities() const
+isl::union_set set::unite(const isl::union_set &uset2) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  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())
+    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_set_detect_equalities(copy());
+  auto res = isl_set_universe(space.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::val set::dim_max_val(int pos) const
+isl::basic_set set::unshifted_simple_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_dim_max_val(copy(), pos);
+  auto res = isl_set_unshifted_simple_hull(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::val set::dim_min_val(int pos) const
+isl::map set::unwrap() 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_dim_min_val(copy(), pos);
+  auto res = isl_set_unwrap(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::empty(isl::space space)
+isl::set set::upper_bound(isl::multi_pw_aff upper) const
 {
-  if (space.is_null())
+  if (!ptr || upper.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_set_empty(space.release());
+  auto res = isl_set_upper_bound_multi_pw_aff(copy(), upper.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::flatten() const
+isl::set set::upper_bound(isl::multi_val upper) const
 {
-  if (!ptr)
+  if (!ptr || upper.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_flatten(copy());
+  auto res = isl_set_upper_bound_multi_val(copy(), upper.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-void set::foreach_basic_set(const std::function<void(isl::basic_set)> &fn) const
+inline std::ostream &operator<<(std::ostream &os, const set &obj)
 {
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_set_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_set_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
+// implementations for isl::space
+space manage(__isl_take isl_space *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  return space(ptr);
+}
+space manage_copy(__isl_keep isl_space *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_space_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  struct fn_data {
-    std::function<void(isl::basic_set)> func;
-    std::exception_ptr eptr;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_basic_set *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_set_foreach_basic_set(get(), fn_lambda, &fn_data);
-  if (fn_data.eptr)
-    std::rethrow_exception(fn_data.eptr);
-  if (res < 0)
+  ptr = isl_space_copy(ptr);
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return;
+  return space(ptr);
+}
+
+space::space()
+    : ptr(nullptr) {}
+
+space::space(const space &obj)
+    : ptr(nullptr)
+{
+  if (!obj.ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_space_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);
+}
+
+space::space(__isl_take isl_space *ptr)
+    : ptr(ptr) {}
+
+space &space::operator=(space obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+space::~space() {
+  if (ptr)
+    isl_space_free(ptr);
+}
+
+__isl_give isl_space *space::copy() const & {
+  return isl_space_copy(ptr);
+}
+
+__isl_keep isl_space *space::get() const {
+  return ptr;
+}
+
+__isl_give isl_space *space::release() {
+  isl_space *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
 }
 
-void set::foreach_point(const std::function<void(isl::point)> &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::point)> func;
-    std::exception_ptr eptr;
-  } fn_data = { fn };
-  auto fn_lambda = [](isl_point *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_set_foreach_point(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;
+bool space::is_null() const {
+  return ptr == nullptr;
 }
 
-isl::multi_val set::plain_multi_val_if_fixed() const
+isl::ctx space::ctx() const {
+  return isl::ctx(isl_space_get_ctx(ptr));
+}
+
+isl::space space::add_named_tuple(isl::id tuple_id, unsigned int dim) const
 {
-  if (!ptr)
+  if (!ptr || tuple_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_set_get_plain_multi_val_if_fixed(get());
+  auto res = isl_space_add_named_tuple_id_ui(copy(), tuple_id.release(), dim);
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_val set::get_plain_multi_val_if_fixed() const
+isl::space space::add_named_tuple(const std::string &tuple_id, unsigned int dim) const
 {
-  return plain_multi_val_if_fixed();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add_named_tuple(isl::id(ctx(), tuple_id), dim);
 }
 
-isl::fixed_box set::simple_fixed_box_hull() const
+isl::space space::add_param(isl::id id) const
 {
-  if (!ptr)
+  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_set_get_simple_fixed_box_hull(get());
+  auto res = isl_space_add_param_id(copy(), id.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::fixed_box set::get_simple_fixed_box_hull() const
+isl::space space::add_param(const std::string &id) const
 {
-  return simple_fixed_box_hull();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add_param(isl::id(ctx(), id));
 }
 
-isl::space set::space() const
+isl::space space::add_unnamed_tuple(unsigned int 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_get_space(get());
+  auto res = isl_space_add_unnamed_tuple_ui(copy(), dim);
   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
+isl::space space::curry() 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);
+  auto res = isl_space_curry(copy());
   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::gist(isl::set context) const
+isl::space space::domain() const
 {
-  if (!ptr || context.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_set_gist(copy(), context.release());
+  auto res = isl_space_domain(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::map set::identity() const
+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_set_identity(copy());
+  auto res = isl_space_domain_map_multi_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_aff set::indicator_function() const
+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_set_indicator_function(copy());
+  auto res = isl_space_domain_map_pw_multi_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::map set::insert_domain(isl::space domain) const
+isl::id space::domain_tuple_id() const
 {
-  if (!ptr || domain.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_set_insert_domain(copy(), domain.release());
+  auto res = isl_space_get_domain_tuple_id(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::intersect(isl::set set2) const
+isl::id space::get_domain_tuple_id() const
 {
-  if (!ptr || set2.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_intersect(copy(), set2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return domain_tuple_id();
 }
 
-isl::set set::intersect_params(isl::set params) const
+isl::space space::flatten_domain() const
 {
-  if (!ptr || params.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_set_intersect_params(copy(), params.release());
+  auto res = isl_space_flatten_domain(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool set::involves_locals() const
+isl::space space::flatten_range() 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_involves_locals(get());
-  if (res < 0)
+  auto res = isl_space_flatten_range(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-bool set::is_disjoint(const isl::set &set2) const
+bool space::has_domain_tuple_id() const
 {
-  if (!ptr || set2.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_set_is_disjoint(get(), set2.get());
+  auto res = isl_space_has_domain_tuple_id(get());
   if (res < 0)
     exception::throw_last_error(saved_ctx);
   return res;
 }
 
-bool set::is_empty() const
+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_set_is_empty(get());
+  auto res = isl_space_has_range_tuple_id(get());
   if (res < 0)
     exception::throw_last_error(saved_ctx);
   return res;
 }
 
-bool set::is_equal(const isl::set &set2) const
+isl::multi_aff space::identity_multi_aff_on_domain() const
 {
-  if (!ptr || set2.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_set_is_equal(get(), set2.get());
-  if (res < 0)
+  auto res = isl_space_identity_multi_aff_on_domain(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-bool set::is_singleton() const
+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_set_is_singleton(get());
-  if (res < 0)
+  auto res = isl_space_identity_multi_pw_aff_on_domain(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-bool set::is_strict_subset(const isl::set &set2) const
+isl::pw_multi_aff space::identity_pw_multi_aff_on_domain() const
 {
-  if (!ptr || set2.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_set_is_strict_subset(get(), set2.get());
-  if (res < 0)
+  auto res = isl_space_identity_pw_multi_aff_on_domain(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-bool set::is_subset(const isl::set &set2) const
+bool space::is_equal(const isl::space &space2) const
 {
-  if (!ptr || set2.is_null())
+  if (!ptr || space2.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_is_subset(get(), set2.get());
+  auto res = isl_space_is_equal(get(), space2.get());
   if (res < 0)
     exception::throw_last_error(saved_ctx);
   return res;
 }
 
-bool set::is_wrapping() const
+bool space::is_wrapping() 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_is_wrapping(get());
+  auto res = isl_space_is_wrapping(get());
   if (res < 0)
     exception::throw_last_error(saved_ctx);
   return res;
 }
 
-isl::set set::lexmax() const
+isl::space space::map_from_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_lexmax(copy());
+  auto res = isl_space_map_from_set(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::pw_multi_aff set::lexmax_pw_multi_aff() const
+isl::multi_aff space::multi_aff(isl::aff_list list) const
 {
-  if (!ptr)
+  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_set_lexmax_pw_multi_aff(copy());
+  auto res = isl_space_multi_aff(copy(), list.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::lexmin() const
+isl::multi_aff space::multi_aff_on_domain(isl::multi_val mv) const
 {
-  if (!ptr)
+  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_lexmin(copy());
+  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::pw_multi_aff set::lexmin_pw_multi_aff() const
+isl::multi_id space::multi_id(isl::id_list list) const
 {
-  if (!ptr)
+  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_set_lexmin_pw_multi_aff(copy());
+  auto res = isl_space_multi_id(copy(), list.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::lower_bound(isl::multi_pw_aff lower) const
+isl::multi_pw_aff space::multi_pw_aff(isl::pw_aff_list list) const
 {
-  if (!ptr || lower.is_null())
+  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_set_lower_bound_multi_pw_aff(copy(), lower.release());
+  auto res = isl_space_multi_pw_aff(copy(), list.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::lower_bound(isl::multi_val lower) const
+isl::multi_union_pw_aff space::multi_union_pw_aff(isl::union_pw_aff_list list) const
 {
-  if (!ptr || lower.is_null())
+  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_set_lower_bound_multi_val(copy(), lower.release());
+  auto res = isl_space_multi_union_pw_aff(copy(), list.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff set::max_multi_pw_aff() const
+isl::multi_val space::multi_val(isl::val_list list) const
 {
-  if (!ptr)
+  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_set_max_multi_pw_aff(copy());
+  auto res = isl_space_multi_val(copy(), list.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::val set::max_val(const isl::aff &obj) const
+isl::aff space::param_aff_on_domain(isl::id id) const
 {
-  if (!ptr || obj.is_null())
+  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_set_max_val(get(), obj.get());
+  auto res = isl_space_param_aff_on_domain_id(copy(), id.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::multi_pw_aff set::min_multi_pw_aff() const
+isl::aff space::param_aff_on_domain(const std::string &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_set_min_multi_pw_aff(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->param_aff_on_domain(isl::id(ctx(), id));
 }
 
-isl::val set::min_val(const isl::aff &obj) const
+isl::space space::params() const
 {
-  if (!ptr || obj.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_set_min_val(get(), obj.get());
+  auto res = isl_space_params(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::params() const
+isl::space space::product(isl::space right) const
 {
-  if (!ptr)
+  if (!ptr || right.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_params(copy());
+  auto res = isl_space_product(copy(), right.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::basic_set set::polyhedral_hull() const
+isl::space space::range() 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_polyhedral_hull(copy());
+  auto res = isl_space_range(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::preimage(isl::multi_aff ma) const
+isl::multi_aff space::range_map_multi_aff() const
 {
-  if (!ptr || ma.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_set_preimage_multi_aff(copy(), ma.release());
+  auto res = isl_space_range_map_multi_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::preimage(isl::multi_pw_aff mpa) const
+isl::pw_multi_aff space::range_map_pw_multi_aff() const
 {
-  if (!ptr || mpa.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_set_preimage_multi_pw_aff(copy(), mpa.release());
+  auto res = isl_space_range_map_pw_multi_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::preimage(isl::pw_multi_aff pma) const
+isl::space space::range_reverse() const
 {
-  if (!ptr || pma.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_set_preimage_pw_multi_aff(copy(), pma.release());
+  auto res = isl_space_range_reverse(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::product(isl::set set2) const
+isl::id space::range_tuple_id() const
 {
-  if (!ptr || set2.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_set_product(copy(), set2.release());
+  auto res = isl_space_get_range_tuple_id(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::project_out_all_params() const
+isl::id space::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
+isl::space space::reverse() 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_project_out_all_params(copy());
+  auto res = isl_space_reverse(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::project_out_param(isl::id id) const
+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_set_project_out_param_id(copy(), id.release());
+  auto res = isl_space_set_domain_tuple_id(copy(), id.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::project_out_param(const std::string &id) const
+isl::space space::set_domain_tuple(const std::string &id) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->project_out_param(isl::id(ctx(), id));
+  return this->set_domain_tuple(isl::id(ctx(), id));
 }
 
-isl::set set::project_out_param(isl::id_list list) const
+isl::space space::set_range_tuple(isl::id id) const
 {
-  if (!ptr || list.is_null())
+  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_set_project_out_param_id_list(copy(), list.release());
+  auto res = isl_space_set_range_tuple_id(copy(), id.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::basic_set set::sample() const
+isl::space space::set_range_tuple(const std::string &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_set_sample(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->set_range_tuple(isl::id(ctx(), id));
 }
 
-isl::point set::sample_point() const
+isl::space space::uncurry() 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_sample_point(copy());
+  auto res = isl_space_uncurry(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::subtract(isl::set set2) const
+isl::space space::unit(isl::ctx ctx)
 {
-  if (!ptr || set2.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = ctx;
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_set_subtract(copy(), set2.release());
+  auto res = isl_space_unit(ctx.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::map set::translation() const
+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_set_translation(copy());
+  auto res = isl_space_universe_map(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::unbind_params(isl::multi_id tuple) const
+isl::set space::universe_set() const
 {
-  if (!ptr || tuple.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_set_unbind_params(copy(), tuple.release());
+  auto res = isl_space_universe_set(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::map set::unbind_params_insert_domain(isl::multi_id domain) const
+isl::space space::unwrap() const
 {
-  if (!ptr || domain.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_set_unbind_params_insert_domain(copy(), domain.release());
+  auto res = isl_space_unwrap(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::unite(isl::set set2) const
+isl::space space::wrap() const
 {
-  if (!ptr || set2.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_set_union(copy(), set2.release());
+  auto res = isl_space_wrap(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::universe(isl::space space)
+isl::aff space::zero_aff_on_domain() const
 {
-  if (space.is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_set_universe(space.release());
+  auto res = isl_space_zero_aff_on_domain(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::basic_set set::unshifted_simple_hull() const
+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_set_unshifted_simple_hull(copy());
+  auto res = isl_space_zero_multi_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::map set::unwrap() const
+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_set_unwrap(copy());
+  auto res = isl_space_zero_multi_pw_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::upper_bound(isl::multi_pw_aff upper) const
+isl::multi_union_pw_aff space::zero_multi_union_pw_aff() const
 {
-  if (!ptr || upper.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_set_upper_bound_multi_pw_aff(copy(), upper.release());
+  auto res = isl_space_zero_multi_union_pw_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::set set::upper_bound(isl::multi_val upper) const
+isl::multi_val space::zero_multi_val() const
 {
-  if (!ptr || upper.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_set_upper_bound_multi_val(copy(), upper.release());
+  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 set &obj)
+inline std::ostream &operator<<(std::ostream &os, const space &obj)
 {
   if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_set_get_ctx(obj.get());
+  auto saved_ctx = isl_space_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_set_to_str(obj.get());
+  char *str = isl_space_to_str(obj.get());
   if (!str)
     exception::throw_last_error(saved_ctx);
   os << str;
@@ -15239,301 +23552,347 @@ inline std::ostream &operator<<(std::ostream &os, const set &obj)
   return os;
 }
 
-// implementations for isl::space
-space manage(__isl_take isl_space *ptr) {
+// implementations for isl::union_access_info
+union_access_info manage(__isl_take isl_union_access_info *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return space(ptr);
+  return union_access_info(ptr);
 }
-space manage_copy(__isl_keep isl_space *ptr) {
+union_access_info manage_copy(__isl_keep isl_union_access_info *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_space_get_ctx(ptr);
+  auto saved_ctx = isl_union_access_info_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_space_copy(ptr);
+  ptr = isl_union_access_info_copy(ptr);
   if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return space(ptr);
+  return union_access_info(ptr);
 }
 
-space::space()
+union_access_info::union_access_info()
     : ptr(nullptr) {}
 
-space::space(const space &obj)
+union_access_info::union_access_info(const union_access_info &obj)
     : ptr(nullptr)
 {
   if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_space_get_ctx(obj.ptr);
+  auto saved_ctx = isl_union_access_info_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);
 }
 
-space::space(__isl_take isl_space *ptr)
+union_access_info::union_access_info(__isl_take isl_union_access_info *ptr)
     : ptr(ptr) {}
 
-space &space::operator=(space obj) {
+union_access_info::union_access_info(isl::union_map sink)
+{
+  if (sink.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = sink.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_access_info_from_sink(sink.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+union_access_info &union_access_info::operator=(union_access_info obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-space::~space() {
+union_access_info::~union_access_info() {
   if (ptr)
-    isl_space_free(ptr);
+    isl_union_access_info_free(ptr);
 }
 
-__isl_give isl_space *space::copy() const & {
-  return isl_space_copy(ptr);
+__isl_give isl_union_access_info *union_access_info::copy() const & {
+  return isl_union_access_info_copy(ptr);
 }
 
-__isl_keep isl_space *space::get() const {
+__isl_keep isl_union_access_info *union_access_info::get() const {
   return ptr;
 }
 
-__isl_give isl_space *space::release() {
-  isl_space *tmp = ptr;
+__isl_give isl_union_access_info *union_access_info::release() {
+  isl_union_access_info *tmp = ptr;
   ptr = nullptr;
   return tmp;
 }
 
-bool space::is_null() const {
+bool union_access_info::is_null() const {
   return ptr == nullptr;
 }
 
-isl::ctx space::ctx() const {
-  return isl::ctx(isl_space_get_ctx(ptr));
+isl::ctx union_access_info::ctx() const {
+  return isl::ctx(isl_union_access_info_get_ctx(ptr));
 }
 
-isl::space space::add_named_tuple(isl::id tuple_id, unsigned int dim) const
+isl::union_flow union_access_info::compute_flow() const
 {
-  if (!ptr || tuple_id.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_space_add_named_tuple_id_ui(copy(), tuple_id.release(), dim);
+  auto res = isl_union_access_info_compute_flow(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space space::add_named_tuple(const std::string &tuple_id, unsigned int dim) const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->add_named_tuple(isl::id(ctx(), tuple_id), dim);
-}
-
-isl::space space::add_unnamed_tuple(unsigned int dim) const
+isl::union_access_info union_access_info::set_kill(isl::union_map kill) const
 {
-  if (!ptr)
+  if (!ptr || kill.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_unnamed_tuple_ui(copy(), dim);
+  auto res = isl_union_access_info_set_kill(copy(), kill.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space space::curry() const
+isl::union_access_info union_access_info::set_may_source(isl::union_map may_source) const
 {
-  if (!ptr)
+  if (!ptr || may_source.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_curry(copy());
+  auto res = isl_union_access_info_set_may_source(copy(), may_source.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space space::domain() const
+isl::union_access_info union_access_info::set_must_source(isl::union_map must_source) const
 {
-  if (!ptr)
+  if (!ptr || must_source.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_domain(copy());
+  auto res = isl_union_access_info_set_must_source(copy(), must_source.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space space::flatten_domain() const
+isl::union_access_info union_access_info::set_schedule(isl::schedule schedule) const
 {
-  if (!ptr)
+  if (!ptr || schedule.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_flatten_domain(copy());
+  auto res = isl_union_access_info_set_schedule(copy(), schedule.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space space::flatten_range() const
+isl::union_access_info union_access_info::set_schedule_map(isl::union_map schedule_map) const
 {
-  if (!ptr)
+  if (!ptr || schedule_map.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_flatten_range(copy());
+  auto res = isl_union_access_info_set_schedule_map(copy(), schedule_map.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool space::is_equal(const isl::space &space2) const
+inline std::ostream &operator<<(std::ostream &os, const union_access_info &obj)
 {
-  if (!ptr || space2.is_null())
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_union_access_info_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_space_is_equal(get(), space2.get());
-  if (res < 0)
+  char *str = isl_union_access_info_to_str(obj.get());
+  if (!str)
     exception::throw_last_error(saved_ctx);
-  return res;
+  os << str;
+  free(str);
+  return os;
 }
 
-bool space::is_wrapping() const
-{
+// implementations for isl::union_flow
+union_flow manage(__isl_take isl_union_flow *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  return union_flow(ptr);
+}
+union_flow manage_copy(__isl_keep isl_union_flow *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_union_flow_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_space_is_wrapping(get());
-  if (res < 0)
+  ptr = isl_union_flow_copy(ptr);
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return union_flow(ptr);
 }
 
-isl::space space::map_from_set() const
+union_flow::union_flow()
+    : ptr(nullptr) {}
+
+union_flow::union_flow(const union_flow &obj)
+    : ptr(nullptr)
 {
-  if (!ptr)
+  if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_union_flow_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_space_map_from_set(copy());
-  if (!res)
+  ptr = obj.copy();
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
 }
 
-isl::space space::params() const
+union_flow::union_flow(__isl_take isl_union_flow *ptr)
+    : ptr(ptr) {}
+
+union_flow &union_flow::operator=(union_flow obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+union_flow::~union_flow() {
+  if (ptr)
+    isl_union_flow_free(ptr);
+}
+
+__isl_give isl_union_flow *union_flow::copy() const & {
+  return isl_union_flow_copy(ptr);
+}
+
+__isl_keep isl_union_flow *union_flow::get() const {
+  return ptr;
+}
+
+__isl_give isl_union_flow *union_flow::release() {
+  isl_union_flow *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool union_flow::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx union_flow::ctx() const {
+  return isl::ctx(isl_union_flow_get_ctx(ptr));
+}
+
+isl::union_map union_flow::full_may_dependence() 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_params(copy());
+  auto res = isl_union_flow_get_full_may_dependence(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space space::product(isl::space right) const
+isl::union_map union_flow::get_full_may_dependence() const
 {
-  if (!ptr || right.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_product(copy(), right.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return full_may_dependence();
 }
 
-isl::space space::range() const
+isl::union_map union_flow::full_must_dependence() 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(copy());
+  auto res = isl_union_flow_get_full_must_dependence(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space space::range_reverse() const
+isl::union_map union_flow::get_full_must_dependence() const
+{
+  return full_must_dependence();
+}
+
+isl::union_map union_flow::may_dependence() 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_reverse(copy());
+  auto res = isl_union_flow_get_may_dependence(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space space::reverse() const
+isl::union_map union_flow::get_may_dependence() const
+{
+  return may_dependence();
+}
+
+isl::union_map union_flow::may_no_source() 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_reverse(copy());
+  auto res = isl_union_flow_get_may_no_source(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space space::uncurry() const
+isl::union_map union_flow::get_may_no_source() const
+{
+  return may_no_source();
+}
+
+isl::union_map union_flow::must_dependence() 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_uncurry(copy());
+  auto res = isl_union_flow_get_must_dependence(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space space::unit(isl::ctx ctx)
+isl::union_map union_flow::get_must_dependence() const
 {
-  auto saved_ctx = ctx;
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_space_unit(ctx.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return must_dependence();
 }
 
-isl::space space::unwrap() const
+isl::union_map union_flow::must_no_source() 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_unwrap(copy());
+  auto res = isl_union_flow_get_must_no_source(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space space::wrap() const
+isl::union_map union_flow::get_must_no_source() 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_wrap(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return must_no_source();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const space &obj)
+inline std::ostream &operator<<(std::ostream &os, const union_flow &obj)
 {
   if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_space_get_ctx(obj.get());
+  auto saved_ctx = isl_union_flow_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_space_to_str(obj.get());
+  char *str = isl_union_flow_to_str(obj.get());
   if (!str)
     exception::throw_last_error(saved_ctx);
   os << str;
@@ -15541,1613 +23900,1675 @@ inline std::ostream &operator<<(std::ostream &os, const space &obj)
   return os;
 }
 
-// implementations for isl::union_access_info
-union_access_info manage(__isl_take isl_union_access_info *ptr) {
+// implementations for isl::union_map
+union_map manage(__isl_take isl_union_map *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return union_access_info(ptr);
+  return union_map(ptr);
 }
-union_access_info manage_copy(__isl_keep isl_union_access_info *ptr) {
+union_map manage_copy(__isl_keep isl_union_map *ptr) {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_union_access_info_get_ctx(ptr);
+  auto saved_ctx = isl_union_map_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_union_access_info_copy(ptr);
+  ptr = isl_union_map_copy(ptr);
   if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return union_access_info(ptr);
+  return union_map(ptr);
 }
 
-union_access_info::union_access_info()
+union_map::union_map()
     : ptr(nullptr) {}
 
-union_access_info::union_access_info(const union_access_info &obj)
+union_map::union_map(const union_map &obj)
     : ptr(nullptr)
 {
   if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_union_access_info_get_ctx(obj.ptr);
+  auto saved_ctx = isl_union_map_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);
 }
 
-union_access_info::union_access_info(__isl_take isl_union_access_info *ptr)
+union_map::union_map(__isl_take isl_union_map *ptr)
     : ptr(ptr) {}
 
-union_access_info::union_access_info(isl::union_map sink)
+union_map::union_map(isl::basic_map bmap)
 {
-  if (sink.is_null())
+  if (bmap.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = sink.ctx();
+  auto saved_ctx = bmap.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_access_info_from_sink(sink.release());
+  auto res = isl_union_map_from_basic_map(bmap.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   ptr = res;
 }
 
-union_access_info &union_access_info::operator=(union_access_info obj) {
+union_map::union_map(isl::map map)
+{
+  if (map.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = map.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_map_from_map(map.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+union_map::union_map(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_map_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+union_map &union_map::operator=(union_map obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
 }
 
-union_access_info::~union_access_info() {
+union_map::~union_map() {
   if (ptr)
-    isl_union_access_info_free(ptr);
+    isl_union_map_free(ptr);
 }
 
-__isl_give isl_union_access_info *union_access_info::copy() const & {
-  return isl_union_access_info_copy(ptr);
+__isl_give isl_union_map *union_map::copy() const & {
+  return isl_union_map_copy(ptr);
 }
 
-__isl_keep isl_union_access_info *union_access_info::get() const {
+__isl_keep isl_union_map *union_map::get() const {
   return ptr;
 }
 
-__isl_give isl_union_access_info *union_access_info::release() {
-  isl_union_access_info *tmp = ptr;
+__isl_give isl_union_map *union_map::release() {
+  isl_union_map *tmp = ptr;
   ptr = nullptr;
   return tmp;
 }
 
-bool union_access_info::is_null() const {
+bool union_map::is_null() const {
   return ptr == nullptr;
 }
 
-isl::ctx union_access_info::ctx() const {
-  return isl::ctx(isl_union_access_info_get_ctx(ptr));
+isl::ctx union_map::ctx() const {
+  return isl::ctx(isl_union_map_get_ctx(ptr));
 }
 
-isl::union_flow union_access_info::compute_flow() const
+isl::union_map union_map::affine_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_union_access_info_compute_flow(copy());
+  auto res = isl_union_map_affine_hull(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_access_info union_access_info::set_kill(isl::union_map kill) const
+isl::union_map union_map::apply_domain(isl::union_map umap2) const
 {
-  if (!ptr || kill.is_null())
+  if (!ptr || umap2.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_union_access_info_set_kill(copy(), kill.release());
+  auto res = isl_union_map_apply_domain(copy(), umap2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_access_info union_access_info::set_may_source(isl::union_map may_source) const
+isl::union_map union_map::apply_range(isl::union_map umap2) const
 {
-  if (!ptr || may_source.is_null())
+  if (!ptr || umap2.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_union_access_info_set_may_source(copy(), may_source.release());
+  auto res = isl_union_map_apply_range(copy(), umap2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_access_info union_access_info::set_must_source(isl::union_map must_source) const
+isl::map union_map::as_map() const
 {
-  if (!ptr || must_source.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_union_access_info_set_must_source(copy(), must_source.release());
+  auto res = isl_union_map_as_map(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_access_info union_access_info::set_schedule(isl::schedule schedule) const
+isl::multi_union_pw_aff union_map::as_multi_union_pw_aff() const
 {
-  if (!ptr || schedule.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_union_access_info_set_schedule(copy(), schedule.release());
+  auto res = isl_union_map_as_multi_union_pw_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_access_info union_access_info::set_schedule_map(isl::union_map schedule_map) const
+isl::union_pw_multi_aff union_map::as_union_pw_multi_aff() const
 {
-  if (!ptr || schedule_map.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_union_access_info_set_schedule_map(copy(), schedule_map.release());
+  auto res = isl_union_map_as_union_pw_multi_aff(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const union_access_info &obj)
+isl::union_set union_map::bind_range(isl::multi_id tuple) const
 {
-  if (!obj.get())
+  if (!ptr || tuple.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_union_access_info_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_union_access_info_to_str(obj.get());
-  if (!str)
+  auto res = isl_union_map_bind_range(copy(), tuple.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::union_flow
-union_flow manage(__isl_take isl_union_flow *ptr) {
+isl::union_map union_map::coalesce() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return union_flow(ptr);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_map_coalesce(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
-union_flow manage_copy(__isl_keep isl_union_flow *ptr) {
+
+isl::union_map union_map::compute_divs() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_union_flow_get_ctx(ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_union_flow_copy(ptr);
-  if (!ptr)
+  auto res = isl_union_map_compute_divs(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return union_flow(ptr);
+  return manage(res);
 }
 
-union_flow::union_flow()
-    : ptr(nullptr) {}
-
-union_flow::union_flow(const union_flow &obj)
-    : ptr(nullptr)
+isl::union_map union_map::curry() const
 {
-  if (!obj.ptr)
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_union_flow_get_ctx(obj.ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = obj.copy();
-  if (!ptr)
+  auto res = isl_union_map_curry(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-union_flow::union_flow(__isl_take isl_union_flow *ptr)
-    : ptr(ptr) {}
-
-union_flow &union_flow::operator=(union_flow obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-union_flow::~union_flow() {
-  if (ptr)
-    isl_union_flow_free(ptr);
-}
-
-__isl_give isl_union_flow *union_flow::copy() const & {
-  return isl_union_flow_copy(ptr);
-}
-
-__isl_keep isl_union_flow *union_flow::get() const {
-  return ptr;
-}
-
-__isl_give isl_union_flow *union_flow::release() {
-  isl_union_flow *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+isl::union_set union_map::deltas() 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_deltas(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-bool union_flow::is_null() const {
-  return ptr == nullptr;
+isl::union_map union_map::detect_equalities() 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_detect_equalities(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::ctx union_flow::ctx() const {
-  return isl::ctx(isl_union_flow_get_ctx(ptr));
+isl::union_set union_map::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_union_map_domain(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::union_map union_flow::full_may_dependence() const
+isl::union_map union_map::domain_factor_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_union_flow_get_full_may_dependence(get());
+  auto res = isl_union_map_domain_factor_domain(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_flow::get_full_may_dependence() const
+isl::union_map union_map::domain_factor_range() const
 {
-  return full_may_dependence();
+  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_domain_factor_range(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::union_map union_flow::full_must_dependence() const
+isl::union_map union_map::domain_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_flow_get_full_must_dependence(get());
+  auto res = isl_union_map_domain_map(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_flow::get_full_must_dependence() const
+isl::union_pw_multi_aff union_map::domain_map_union_pw_multi_aff() const
 {
-  return full_must_dependence();
+  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_domain_map_union_pw_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::union_map union_flow::may_dependence() const
+isl::union_map union_map::domain_product(isl::union_map umap2) const
 {
-  if (!ptr)
+  if (!ptr || umap2.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_union_flow_get_may_dependence(get());
+  auto res = isl_union_map_domain_product(copy(), umap2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_flow::get_may_dependence() const
+isl::union_map union_map::empty(isl::ctx ctx)
 {
-  return may_dependence();
+  auto saved_ctx = ctx;
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_map_empty_ctx(ctx.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::union_map union_flow::may_no_source() const
+isl::union_map union_map::eq_at(isl::multi_union_pw_aff mupa) const
 {
-  if (!ptr)
+  if (!ptr || mupa.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_union_flow_get_may_no_source(get());
+  auto res = isl_union_map_eq_at_multi_union_pw_aff(copy(), mupa.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_flow::get_may_no_source() const
+bool union_map::every_map(const std::function<bool(isl::map)> &test) const
 {
-  return may_no_source();
+  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 test_data {
+    std::function<bool(isl::map)> func;
+    std::exception_ptr eptr;
+  } test_data = { test };
+  auto test_lambda = [](isl_map *arg_0, void *arg_1) -> isl_bool {
+    auto *data = static_cast<struct test_data *>(arg_1);
+    ISL_CPP_TRY {
+      auto ret = (data->func)(manage_copy(arg_0));
+      return ret ? isl_bool_true : isl_bool_false;
+    } ISL_CPP_CATCH_ALL {
+      data->eptr = std::current_exception();
+      return isl_bool_error;
+    }
+  };
+  auto res = isl_union_map_every_map(get(), test_lambda, &test_data);
+  if (test_data.eptr)
+    std::rethrow_exception(test_data.eptr);
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
 }
 
-isl::union_map union_flow::must_dependence() const
+isl::map union_map::extract_map(isl::space space) const
 {
-  if (!ptr)
+  if (!ptr || space.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_union_flow_get_must_dependence(get());
+  auto res = isl_union_map_extract_map(get(), space.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_flow::get_must_dependence() const
-{
-  return must_dependence();
-}
-
-isl::union_map union_flow::must_no_source() const
+isl::union_map union_map::factor_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_union_flow_get_must_no_source(get());
+  auto res = isl_union_map_factor_domain(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_flow::get_must_no_source() const
+isl::union_map union_map::factor_range() const
 {
-  return must_no_source();
+  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_factor_range(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-inline std::ostream &operator<<(std::ostream &os, const union_flow &obj)
+isl::union_map union_map::fixed_power(isl::val exp) const
 {
-  if (!obj.get())
+  if (!ptr || exp.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_union_flow_get_ctx(obj.get());
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_union_flow_to_str(obj.get());
-  if (!str)
+  auto res = isl_union_map_fixed_power_val(copy(), exp.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return manage(res);
 }
 
-// implementations for isl::union_map
-union_map manage(__isl_take isl_union_map *ptr) {
+isl::union_map union_map::fixed_power(long exp) const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return union_map(ptr);
+  return this->fixed_power(isl::val(ctx(), exp));
 }
-union_map manage_copy(__isl_keep isl_union_map *ptr) {
+
+void union_map::foreach_map(const std::function<void(isl::map)> &fn) const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_union_map_get_ctx(ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_union_map_copy(ptr);
-  if (!ptr)
+  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_union_map_foreach_map(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 union_map(ptr);
+  return;
 }
 
-union_map::union_map()
-    : ptr(nullptr) {}
-
-union_map::union_map(const union_map &obj)
-    : ptr(nullptr)
+isl::union_map union_map::from(isl::multi_union_pw_aff mupa)
 {
-  if (!obj.ptr)
+  if (mupa.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_union_map_get_ctx(obj.ptr);
+  auto saved_ctx = mupa.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = obj.copy();
-  if (!ptr)
+  auto res = isl_union_map_from_multi_union_pw_aff(mupa.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-union_map::union_map(__isl_take isl_union_map *ptr)
-    : ptr(ptr) {}
-
-union_map::union_map(isl::basic_map bmap)
+isl::union_map union_map::from(isl::union_pw_multi_aff upma)
 {
-  if (bmap.is_null())
+  if (upma.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = bmap.ctx();
+  auto saved_ctx = upma.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_from_basic_map(bmap.release());
+  auto res = isl_union_map_from_union_pw_multi_aff(upma.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-union_map::union_map(isl::map map)
+isl::union_map union_map::from_domain(isl::union_set uset)
 {
-  if (map.is_null())
+  if (uset.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = map.ctx();
+  auto saved_ctx = uset.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_from_map(map.release());
+  auto res = isl_union_map_from_domain(uset.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return manage(res);
 }
 
-union_map::union_map(isl::ctx ctx, const std::string &str)
+isl::union_map union_map::from_domain_and_range(isl::union_set domain, isl::union_set range)
 {
-  auto saved_ctx = ctx;
+  if (domain.is_null() || range.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_union_map_read_from_str(ctx.release(), str.c_str());
+  auto res = isl_union_map_from_domain_and_range(domain.release(), range.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
-  ptr = res;
-}
-
-union_map &union_map::operator=(union_map obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
-}
-
-union_map::~union_map() {
-  if (ptr)
-    isl_union_map_free(ptr);
-}
-
-__isl_give isl_union_map *union_map::copy() const & {
-  return isl_union_map_copy(ptr);
-}
-
-__isl_keep isl_union_map *union_map::get() const {
-  return ptr;
+  return manage(res);
 }
 
-__isl_give isl_union_map *union_map::release() {
-  isl_union_map *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+isl::union_map union_map::from_range(isl::union_set uset)
+{
+  if (uset.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = uset.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_map_from_range(uset.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-bool union_map::is_null() const {
-  return ptr == nullptr;
+isl::union_map union_map::gist(isl::union_map context) const
+{
+  if (!ptr || context.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_union_map_gist(copy(), context.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::ctx union_map::ctx() const {
-  return isl::ctx(isl_union_map_get_ctx(ptr));
+isl::union_map union_map::gist_domain(isl::union_set uset) const
+{
+  if (!ptr || uset.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_union_map_gist_domain(copy(), uset.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-isl::union_map union_map::affine_hull() const
+isl::union_map union_map::gist_params(isl::set set) const
 {
-  if (!ptr)
+  if (!ptr || set.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_union_map_affine_hull(copy());
+  auto res = isl_union_map_gist_params(copy(), set.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::apply_domain(isl::union_map umap2) const
+isl::union_map union_map::gist_range(isl::union_set uset) const
 {
-  if (!ptr || umap2.is_null())
+  if (!ptr || uset.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_union_map_apply_domain(copy(), umap2.release());
+  auto res = isl_union_map_gist_range(copy(), uset.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::apply_range(isl::union_map umap2) const
+isl::union_map union_map::intersect(isl::union_map umap2) const
 {
   if (!ptr || umap2.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_union_map_apply_range(copy(), umap2.release());
+  auto res = isl_union_map_intersect(copy(), umap2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_set union_map::bind_range(isl::multi_id tuple) const
+isl::union_map union_map::intersect_domain(isl::space space) const
 {
-  if (!ptr || tuple.is_null())
+  if (!ptr || space.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_union_map_bind_range(copy(), tuple.release());
+  auto res = isl_union_map_intersect_domain_space(copy(), space.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::coalesce() const
+isl::union_map union_map::intersect_domain(isl::union_set uset) const
 {
-  if (!ptr)
+  if (!ptr || uset.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_union_map_coalesce(copy());
+  auto res = isl_union_map_intersect_domain_union_set(copy(), uset.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::compute_divs() const
+isl::union_map union_map::intersect_domain_factor_domain(isl::union_map factor) const
 {
-  if (!ptr)
+  if (!ptr || factor.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_union_map_compute_divs(copy());
+  auto res = isl_union_map_intersect_domain_factor_domain(copy(), factor.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::curry() const
+isl::union_map union_map::intersect_domain_factor_range(isl::union_map factor) const
 {
-  if (!ptr)
+  if (!ptr || factor.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_union_map_curry(copy());
+  auto res = isl_union_map_intersect_domain_factor_range(copy(), factor.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_set union_map::deltas() const
+isl::union_map union_map::intersect_params(isl::set set) const
 {
-  if (!ptr)
+  if (!ptr || set.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_union_map_deltas(copy());
+  auto res = isl_union_map_intersect_params(copy(), set.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::detect_equalities() const
+isl::union_map union_map::intersect_range(isl::space space) const
 {
-  if (!ptr)
+  if (!ptr || space.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_union_map_detect_equalities(copy());
+  auto res = isl_union_map_intersect_range_space(copy(), space.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_set union_map::domain() const
+isl::union_map union_map::intersect_range(isl::union_set uset) const
 {
-  if (!ptr)
+  if (!ptr || uset.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_union_map_domain(copy());
+  auto res = isl_union_map_intersect_range_union_set(copy(), uset.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::domain_factor_domain() const
+isl::union_map union_map::intersect_range_factor_domain(isl::union_map factor) const
 {
-  if (!ptr)
+  if (!ptr || factor.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_union_map_domain_factor_domain(copy());
+  auto res = isl_union_map_intersect_range_factor_domain(copy(), factor.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::domain_factor_range() const
+isl::union_map union_map::intersect_range_factor_range(isl::union_map factor) const
 {
-  if (!ptr)
+  if (!ptr || factor.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_union_map_domain_factor_range(copy());
+  auto res = isl_union_map_intersect_range_factor_range(copy(), factor.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::domain_map() const
+bool union_map::is_bijective() 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_domain_map(copy());
-  if (!res)
+  auto res = isl_union_map_is_bijective(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::union_pw_multi_aff union_map::domain_map_union_pw_multi_aff() const
+bool union_map::is_disjoint(const isl::union_map &umap2) const
+{
+  if (!ptr || umap2.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_union_map_is_disjoint(get(), umap2.get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+bool union_map::is_empty() 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_domain_map_union_pw_multi_aff(copy());
-  if (!res)
+  auto res = isl_union_map_is_empty(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::union_map union_map::domain_product(isl::union_map umap2) const
+bool union_map::is_equal(const isl::union_map &umap2) const
 {
   if (!ptr || umap2.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_union_map_domain_product(copy(), umap2.release());
-  if (!res)
+  auto res = isl_union_map_is_equal(get(), umap2.get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::union_map union_map::empty(isl::ctx ctx)
+bool union_map::is_injective() const
 {
-  auto saved_ctx = ctx;
+  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_empty_ctx(ctx.release());
-  if (!res)
+  auto res = isl_union_map_is_injective(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-isl::union_map union_map::eq_at(isl::multi_union_pw_aff mupa) const
+bool union_map::is_single_valued() const
 {
-  if (!ptr || mupa.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_union_map_eq_at_multi_union_pw_aff(copy(), mupa.release());
-  if (!res)
+  auto res = isl_union_map_is_single_valued(get());
+  if (res < 0)
     exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return res;
 }
 
-bool union_map::every_map(const std::function<bool(isl::map)> &test) const
+bool union_map::is_strict_subset(const isl::union_map &umap2) const
+{
+  if (!ptr || umap2.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_union_map_is_strict_subset(get(), umap2.get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+bool union_map::is_subset(const isl::union_map &umap2) const
+{
+  if (!ptr || umap2.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_union_map_is_subset(get(), umap2.get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+bool union_map::isa_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);
-  struct test_data {
-    std::function<bool(isl::map)> func;
-    std::exception_ptr eptr;
-  } test_data = { test };
-  auto test_lambda = [](isl_map *arg_0, void *arg_1) -> isl_bool {
-    auto *data = static_cast<struct test_data *>(arg_1);
-    ISL_CPP_TRY {
-      auto ret = (data->func)(manage_copy(arg_0));
-      return ret ? isl_bool_true : isl_bool_false;
-    } ISL_CPP_CATCH_ALL {
-      data->eptr = std::current_exception();
-      return isl_bool_error;
-    }
-  };
-  auto res = isl_union_map_every_map(get(), test_lambda, &test_data);
-  if (test_data.eptr)
-    std::rethrow_exception(test_data.eptr);
+  auto res = isl_union_map_isa_map(get());
   if (res < 0)
     exception::throw_last_error(saved_ctx);
   return res;
 }
 
-isl::map union_map::extract_map(isl::space space) const
+isl::union_map union_map::lexmax() const
 {
-  if (!ptr || space.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_union_map_extract_map(get(), space.release());
+  auto res = isl_union_map_lexmax(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::factor_domain() const
+isl::union_map union_map::lexmin() 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_factor_domain(copy());
+  auto res = isl_union_map_lexmin(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::factor_range() const
+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_factor_range(copy());
+  auto res = isl_union_map_get_map_list(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::fixed_power(isl::val exp) const
+isl::map_list union_map::get_map_list() const
 {
-  if (!ptr || exp.is_null())
+  return map_list();
+}
+
+isl::union_map union_map::polyhedral_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_union_map_fixed_power_val(copy(), exp.release());
+  auto res = isl_union_map_polyhedral_hull(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::fixed_power(long exp) const
+isl::union_map union_map::preimage_domain(isl::multi_aff ma) const
 {
-  if (!ptr)
+  if (!ptr || ma.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return this->fixed_power(isl::val(ctx(), exp));
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_map_preimage_domain_multi_aff(copy(), ma.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
 }
 
-void union_map::foreach_map(const std::function<void(isl::map)> &fn) const
+isl::union_map union_map::preimage_domain(isl::multi_pw_aff mpa) const
 {
-  if (!ptr)
+  if (!ptr || mpa.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);
-  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_union_map_foreach_map(get(), fn_lambda, &fn_data);
-  if (fn_data.eptr)
-    std::rethrow_exception(fn_data.eptr);
-  if (res < 0)
+  auto res = isl_union_map_preimage_domain_multi_pw_aff(copy(), mpa.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return;
+  return manage(res);
 }
 
-isl::union_map union_map::from(isl::multi_union_pw_aff mupa)
+isl::union_map union_map::preimage_domain(isl::pw_multi_aff pma) const
 {
-  if (mupa.is_null())
+  if (!ptr || pma.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = mupa.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_from_multi_union_pw_aff(mupa.release());
+  auto res = isl_union_map_preimage_domain_pw_multi_aff(copy(), pma.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::from(isl::union_pw_multi_aff upma)
+isl::union_map union_map::preimage_domain(isl::union_pw_multi_aff upma) const
 {
-  if (upma.is_null())
+  if (!ptr || upma.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = upma.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_from_union_pw_multi_aff(upma.release());
+  auto res = isl_union_map_preimage_domain_union_pw_multi_aff(copy(), upma.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_map union_map::preimage_range(isl::multi_aff ma) const
+{
+  if (!ptr || ma.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_union_map_preimage_range_multi_aff(copy(), ma.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::from_domain(isl::union_set uset)
+isl::union_map union_map::preimage_range(isl::pw_multi_aff pma) const
 {
-  if (uset.is_null())
+  if (!ptr || pma.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = uset.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_from_domain(uset.release());
+  auto res = isl_union_map_preimage_range_pw_multi_aff(copy(), pma.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::from_domain_and_range(isl::union_set domain, isl::union_set range)
+isl::union_map union_map::preimage_range(isl::union_pw_multi_aff upma) const
 {
-  if (domain.is_null() || range.is_null())
+  if (!ptr || upma.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = domain.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_from_domain_and_range(domain.release(), range.release());
+  auto res = isl_union_map_preimage_range_union_pw_multi_aff(copy(), upma.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::from_range(isl::union_set uset)
+isl::union_map union_map::product(isl::union_map umap2) const
 {
-  if (uset.is_null())
+  if (!ptr || umap2.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = uset.ctx();
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_from_range(uset.release());
+  auto res = isl_union_map_product(copy(), umap2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space union_map::space() const
+isl::union_map union_map::project_out_all_params() 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());
+  auto res = isl_union_map_project_out_all_params(copy());
   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
+isl::union_set union_map::range() const
 {
-  if (!ptr || context.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_union_map_gist(copy(), context.release());
+  auto res = isl_union_map_range(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::gist_domain(isl::union_set uset) const
+isl::union_map union_map::range_factor_domain() const
 {
-  if (!ptr || uset.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_union_map_gist_domain(copy(), uset.release());
+  auto res = isl_union_map_range_factor_domain(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::gist_params(isl::set set) const
+isl::union_map union_map::range_factor_range() const
 {
-  if (!ptr || set.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_union_map_gist_params(copy(), set.release());
+  auto res = isl_union_map_range_factor_range(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::gist_range(isl::union_set uset) const
+isl::union_map union_map::range_map() const
 {
-  if (!ptr || uset.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_union_map_gist_range(copy(), uset.release());
+  auto res = isl_union_map_range_map(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::intersect(isl::union_map umap2) const
+isl::union_map union_map::range_product(isl::union_map umap2) const
 {
   if (!ptr || umap2.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_union_map_intersect(copy(), umap2.release());
+  auto res = isl_union_map_range_product(copy(), umap2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::intersect_domain(isl::space space) const
+isl::union_map union_map::range_reverse() const
 {
-  if (!ptr || space.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_union_map_intersect_domain_space(copy(), space.release());
+  auto res = isl_union_map_range_reverse(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::intersect_domain(isl::union_set uset) const
+isl::union_map union_map::reverse() const
 {
-  if (!ptr || uset.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_union_map_intersect_domain_union_set(copy(), uset.release());
+  auto res = isl_union_map_reverse(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::intersect_domain_factor_domain(isl::union_map factor) const
+isl::space union_map::space() const
 {
-  if (!ptr || factor.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_union_map_intersect_domain_factor_domain(copy(), factor.release());
+  auto res = isl_union_map_get_space(get());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::intersect_domain_factor_range(isl::union_map factor) const
+isl::space union_map::get_space() const
 {
-  if (!ptr || factor.is_null())
+  return space();
+}
+
+isl::union_map union_map::subtract(isl::union_map umap2) const
+{
+  if (!ptr || umap2.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_union_map_intersect_domain_factor_range(copy(), factor.release());
+  auto res = isl_union_map_subtract(copy(), umap2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::intersect_params(isl::set set) const
+isl::union_map union_map::subtract_domain(isl::union_set dom) const
 {
-  if (!ptr || set.is_null())
+  if (!ptr || dom.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_union_map_intersect_params(copy(), set.release());
+  auto res = isl_union_map_subtract_domain(copy(), dom.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::intersect_range(isl::space space) const
+isl::union_map union_map::subtract_range(isl::union_set dom) const
 {
-  if (!ptr || space.is_null())
+  if (!ptr || dom.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_union_map_intersect_range_space(copy(), space.release());
+  auto res = isl_union_map_subtract_range(copy(), dom.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::intersect_range(isl::union_set uset) const
+isl::union_map union_map::uncurry() const
 {
-  if (!ptr || uset.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_union_map_intersect_range_union_set(copy(), uset.release());
+  auto res = isl_union_map_uncurry(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::intersect_range_factor_domain(isl::union_map factor) const
+isl::union_map union_map::unite(isl::union_map umap2) const
 {
-  if (!ptr || factor.is_null())
+  if (!ptr || umap2.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_union_map_intersect_range_factor_domain(copy(), factor.release());
+  auto res = isl_union_map_union(copy(), umap2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::intersect_range_factor_range(isl::union_map factor) const
+isl::union_map union_map::universe() const
 {
-  if (!ptr || factor.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_union_map_intersect_range_factor_range(copy(), factor.release());
+  auto res = isl_union_map_universe(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-bool union_map::is_bijective() const
+isl::union_set union_map::wrap() 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_is_bijective(get());
-  if (res < 0)
+  auto res = isl_union_map_wrap(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-bool union_map::is_disjoint(const isl::union_map &umap2) const
+isl::union_map union_map::zip() const
 {
-  if (!ptr || umap2.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_union_map_is_disjoint(get(), umap2.get());
-  if (res < 0)
+  auto res = isl_union_map_zip(copy());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return manage(res);
 }
 
-bool union_map::is_empty() const
+inline std::ostream &operator<<(std::ostream &os, const union_map &obj)
 {
-  if (!ptr)
+  if (!obj.get())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_union_map_get_ctx(obj.get());
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_is_empty(get());
-  if (res < 0)
+  char *str = isl_union_map_to_str(obj.get());
+  if (!str)
     exception::throw_last_error(saved_ctx);
-  return res;
+  os << str;
+  free(str);
+  return os;
 }
 
-bool union_map::is_equal(const isl::union_map &umap2) const
-{
-  if (!ptr || umap2.is_null())
+// implementations for isl::union_pw_aff
+union_pw_aff manage(__isl_take isl_union_pw_aff *ptr) {
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  return union_pw_aff(ptr);
+}
+union_pw_aff manage_copy(__isl_keep isl_union_pw_aff *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_union_pw_aff_get_ctx(ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_is_equal(get(), umap2.get());
-  if (res < 0)
+  ptr = isl_union_pw_aff_copy(ptr);
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return res;
+  return union_pw_aff(ptr);
 }
 
-bool union_map::is_injective() const
+union_pw_aff::union_pw_aff()
+    : ptr(nullptr) {}
+
+union_pw_aff::union_pw_aff(const union_pw_aff &obj)
+    : ptr(nullptr)
 {
-  if (!ptr)
+  if (!obj.ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = isl_union_pw_aff_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_is_injective(get());
-  if (res < 0)
+  ptr = obj.copy();
+  if (!ptr)
     exception::throw_last_error(saved_ctx);
-  return res;
 }
 
-bool union_map::is_single_valued() const
+union_pw_aff::union_pw_aff(__isl_take isl_union_pw_aff *ptr)
+    : ptr(ptr) {}
+
+union_pw_aff::union_pw_aff(isl::aff aff)
 {
-  if (!ptr)
+  if (aff.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = aff.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_is_single_valued(get());
-  if (res < 0)
+  auto res = isl_union_pw_aff_from_aff(aff.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  ptr = res;
 }
 
-bool union_map::is_strict_subset(const isl::union_map &umap2) const
+union_pw_aff::union_pw_aff(isl::pw_aff pa)
 {
-  if (!ptr || umap2.is_null())
+  if (pa.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = pa.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_is_strict_subset(get(), umap2.get());
-  if (res < 0)
+  auto res = isl_union_pw_aff_from_pw_aff(pa.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  ptr = res;
 }
 
-bool union_map::is_subset(const isl::union_map &umap2) const
+union_pw_aff::union_pw_aff(isl::ctx ctx, const std::string &str)
 {
-  if (!ptr || umap2.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  auto saved_ctx = ctx;
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_is_subset(get(), umap2.get());
-  if (res < 0)
+  auto res = isl_union_pw_aff_read_from_str(ctx.release(), str.c_str());
+  if (!res)
     exception::throw_last_error(saved_ctx);
-  return res;
+  ptr = res;
+}
+
+union_pw_aff &union_pw_aff::operator=(union_pw_aff obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+union_pw_aff::~union_pw_aff() {
+  if (ptr)
+    isl_union_pw_aff_free(ptr);
+}
+
+__isl_give isl_union_pw_aff *union_pw_aff::copy() const & {
+  return isl_union_pw_aff_copy(ptr);
+}
+
+__isl_keep isl_union_pw_aff *union_pw_aff::get() const {
+  return ptr;
+}
+
+__isl_give isl_union_pw_aff *union_pw_aff::release() {
+  isl_union_pw_aff *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool union_pw_aff::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx union_pw_aff::ctx() const {
+  return isl::ctx(isl_union_pw_aff_get_ctx(ptr));
 }
 
-bool union_map::isa_map() const
+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__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_isa_map(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
+  return isl::multi_union_pw_aff(*this).add(multi2);
 }
 
-isl::union_map union_map::lexmax() const
+isl::union_pw_aff union_pw_aff::add(isl::union_pw_aff upa2) const
 {
-  if (!ptr)
+  if (!ptr || upa2.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_union_map_lexmax(copy());
+  auto res = isl_union_pw_aff_add(copy(), upa2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::lexmin() const
+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__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_lexmin(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_multi_aff(*this).add(upma2);
 }
 
-isl::union_map union_map::polyhedral_hull() const
+isl::union_pw_aff union_pw_aff::add(const isl::aff &upa2) 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_polyhedral_hull(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->add(isl::union_pw_aff(upa2));
 }
 
-isl::union_map union_map::preimage_domain(isl::multi_aff ma) const
+isl::union_pw_aff union_pw_aff::add(const isl::pw_aff &upa2) const
 {
-  if (!ptr || ma.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_union_map_preimage_domain_multi_aff(copy(), ma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->add(isl::union_pw_aff(upa2));
 }
 
-isl::union_map union_map::preimage_domain(isl::multi_pw_aff mpa) const
+isl::union_pw_multi_aff union_pw_aff::apply(const isl::union_pw_multi_aff &upma2) const
 {
-  if (!ptr || mpa.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_union_map_preimage_domain_multi_pw_aff(copy(), mpa.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_multi_aff(*this).apply(upma2);
 }
 
-isl::union_map union_map::preimage_domain(isl::pw_multi_aff pma) const
+isl::multi_union_pw_aff union_pw_aff::as_multi_union_pw_aff() const
 {
-  if (!ptr || pma.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_union_map_preimage_domain_pw_multi_aff(copy(), pma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_multi_aff(*this).as_multi_union_pw_aff();
 }
 
-isl::union_map union_map::preimage_domain(isl::union_pw_multi_aff upma) const
+isl::pw_multi_aff union_pw_aff::as_pw_multi_aff() const
 {
-  if (!ptr || upma.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_union_map_preimage_domain_union_pw_multi_aff(copy(), upma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_multi_aff(*this).as_pw_multi_aff();
 }
 
-isl::union_map union_map::preimage_range(isl::multi_aff ma) const
+isl::union_map union_pw_aff::as_union_map() const
 {
-  if (!ptr || ma.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_union_map_preimage_range_multi_aff(copy(), ma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_multi_aff(*this).as_union_map();
 }
 
-isl::union_map union_map::preimage_range(isl::pw_multi_aff pma) const
+isl::union_pw_aff union_pw_aff::at(int pos) const
 {
-  if (!ptr || pma.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_union_map_preimage_range_pw_multi_aff(copy(), pma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_union_pw_aff(*this).at(pos);
 }
 
-isl::union_map union_map::preimage_range(isl::union_pw_multi_aff upma) const
+isl::union_set union_pw_aff::bind(const isl::multi_id &tuple) const
 {
-  if (!ptr || upma.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_union_map_preimage_range_union_pw_multi_aff(copy(), upma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_union_pw_aff(*this).bind(tuple);
 }
 
-isl::union_map union_map::product(isl::union_map umap2) const
+isl::union_set union_pw_aff::bind(isl::id id) const
 {
-  if (!ptr || umap2.is_null())
+  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_union_map_product(copy(), umap2.release());
+  auto res = isl_union_pw_aff_bind_id(copy(), id.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::project_out_all_params() const
+isl::union_set union_pw_aff::bind(const std::string &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_union_map_project_out_all_params(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->bind(isl::id(ctx(), id));
 }
 
-isl::union_set union_map::range() const
+isl::union_pw_aff union_pw_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_union_map_range(copy());
+  auto res = isl_union_pw_aff_coalesce(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::range_factor_domain() const
+isl::union_set union_pw_aff::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_union_map_range_factor_domain(copy());
+  auto res = isl_union_pw_aff_domain(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::range_factor_range() 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_map_range_factor_range(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_multi_aff(*this).extract_pw_multi_aff(space);
 }
 
-isl::union_map union_map::range_map() const
+isl::multi_union_pw_aff union_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_union_map_range_map(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_union_pw_aff(*this).flat_range_product(multi2);
 }
 
-isl::union_map union_map::range_product(isl::union_map umap2) const
+isl::union_pw_multi_aff union_pw_aff::flat_range_product(const isl::union_pw_multi_aff &upma2) const
 {
-  if (!ptr || umap2.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_union_map_range_product(copy(), umap2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_multi_aff(*this).flat_range_product(upma2);
 }
 
-isl::union_map union_map::range_reverse() const
+isl::union_pw_aff union_pw_aff::gist(isl::union_set context) const
 {
-  if (!ptr)
+  if (!ptr || context.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_union_map_range_reverse(copy());
+  auto res = isl_union_pw_aff_gist(copy(), context.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::reverse() const
+bool 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_union_map_reverse(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_union_pw_aff(*this).has_range_tuple_id();
 }
 
-isl::union_map union_map::subtract(isl::union_map umap2) const
+isl::union_pw_aff union_pw_aff::intersect_domain(isl::space space) const
 {
-  if (!ptr || umap2.is_null())
+  if (!ptr || space.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_union_map_subtract(copy(), umap2.release());
+  auto res = isl_union_pw_aff_intersect_domain_space(copy(), space.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::subtract_domain(isl::union_set dom) const
+isl::union_pw_aff union_pw_aff::intersect_domain(isl::union_set uset) const
 {
-  if (!ptr || dom.is_null())
+  if (!ptr || uset.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_union_map_subtract_domain(copy(), dom.release());
+  auto res = isl_union_pw_aff_intersect_domain_union_set(copy(), uset.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::subtract_range(isl::union_set dom) const
+isl::union_pw_aff union_pw_aff::intersect_domain_wrapped_domain(isl::union_set uset) const
 {
-  if (!ptr || dom.is_null())
+  if (!ptr || uset.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_union_map_subtract_range(copy(), dom.release());
+  auto res = isl_union_pw_aff_intersect_domain_wrapped_domain(copy(), uset.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::uncurry() const
+isl::union_pw_aff union_pw_aff::intersect_domain_wrapped_range(isl::union_set uset) const
 {
-  if (!ptr)
+  if (!ptr || uset.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_union_map_uncurry(copy());
+  auto res = isl_union_pw_aff_intersect_domain_wrapped_range(copy(), uset.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::unite(isl::union_map umap2) const
+isl::union_pw_aff union_pw_aff::intersect_params(isl::set set) const
 {
-  if (!ptr || umap2.is_null())
+  if (!ptr || set.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_union_map_union(copy(), umap2.release());
+  auto res = isl_union_pw_aff_intersect_params(copy(), set.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_map union_map::universe() const
+bool union_pw_aff::involves_locals() 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_universe(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_multi_aff(*this).involves_locals();
 }
 
-isl::union_set union_map::wrap() const
+bool union_pw_aff::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_union_map_wrap(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_union_pw_aff(*this).involves_nan();
 }
 
-isl::union_map union_map::zip() const
+bool union_pw_aff::isa_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_zip(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_multi_aff(*this).isa_pw_multi_aff();
 }
 
-inline std::ostream &operator<<(std::ostream &os, const union_map &obj)
+isl::union_pw_aff_list union_pw_aff::list() const
 {
-  if (!obj.get())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_union_map_get_ctx(obj.get());
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  char *str = isl_union_map_to_str(obj.get());
-  if (!str)
-    exception::throw_last_error(saved_ctx);
-  os << str;
-  free(str);
-  return os;
+  return isl::multi_union_pw_aff(*this).list();
 }
 
-// implementations for isl::union_pw_aff
-union_pw_aff manage(__isl_take isl_union_pw_aff *ptr) {
+isl::multi_union_pw_aff union_pw_aff::neg() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  return union_pw_aff(ptr);
+  return isl::multi_union_pw_aff(*this).neg();
 }
-union_pw_aff manage_copy(__isl_keep isl_union_pw_aff *ptr) {
+
+bool union_pw_aff::plain_is_empty() const
+{
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_union_pw_aff_get_ctx(ptr);
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = isl_union_pw_aff_copy(ptr);
+  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_last_error(saved_ctx);
-  return union_pw_aff(ptr);
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).plain_is_equal(multi2);
 }
 
-union_pw_aff::union_pw_aff()
-    : ptr(nullptr) {}
+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);
+}
 
-union_pw_aff::union_pw_aff(const union_pw_aff &obj)
-    : ptr(nullptr)
+isl::union_pw_aff union_pw_aff::pullback(isl::union_pw_multi_aff upma) const
 {
-  if (!obj.ptr)
+  if (!ptr || upma.is_null())
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = isl_union_pw_aff_get_ctx(obj.ptr);
+  auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  ptr = obj.copy();
-  if (!ptr)
+  auto res = isl_union_pw_aff_pullback_union_pw_multi_aff(copy(), upma.release());
+  if (!res)
     exception::throw_last_error(saved_ctx);
+  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();
 }
 
-union_pw_aff::union_pw_aff(__isl_take isl_union_pw_aff *ptr)
-    : ptr(ptr) {}
-
-union_pw_aff::union_pw_aff(isl::aff aff)
+isl::union_pw_multi_aff union_pw_aff::range_factor_range() const
 {
-  if (aff.is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = aff.ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_pw_aff_from_aff(aff.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return isl::union_pw_multi_aff(*this).range_factor_range();
 }
 
-union_pw_aff::union_pw_aff(isl::pw_aff pa)
+isl::multi_union_pw_aff union_pw_aff::range_product(const isl::multi_union_pw_aff &multi2) const
 {
-  if (pa.is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = pa.ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_pw_aff_from_pw_aff(pa.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
+  return isl::multi_union_pw_aff(*this).range_product(multi2);
 }
 
-union_pw_aff::union_pw_aff(isl::ctx ctx, const std::string &str)
+isl::union_pw_multi_aff union_pw_aff::range_product(const isl::union_pw_multi_aff &upma2) const
 {
-  auto saved_ctx = ctx;
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_pw_aff_read_from_str(ctx.release(), str.c_str());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  ptr = res;
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).range_product(upma2);
 }
 
-union_pw_aff &union_pw_aff::operator=(union_pw_aff obj) {
-  std::swap(this->ptr, obj.ptr);
-  return *this;
+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();
 }
 
-union_pw_aff::~union_pw_aff() {
-  if (ptr)
-    isl_union_pw_aff_free(ptr);
+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_give isl_union_pw_aff *union_pw_aff::copy() const & {
-  return isl_union_pw_aff_copy(ptr);
+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_keep isl_union_pw_aff *union_pw_aff::get() const {
-  return ptr;
+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_give isl_union_pw_aff *union_pw_aff::release() {
-  isl_union_pw_aff *tmp = ptr;
-  ptr = nullptr;
-  return tmp;
+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));
 }
 
-bool union_pw_aff::is_null() const {
-  return ptr == nullptr;
+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::ctx union_pw_aff::ctx() const {
-  return isl::ctx(isl_union_pw_aff_get_ctx(ptr));
+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::union_pw_aff union_pw_aff::add(isl::union_pw_aff upa2) const
+isl::multi_union_pw_aff union_pw_aff::scale_down(long v) const
 {
-  if (!ptr || upa2.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_union_pw_aff_add(copy(), upa2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->scale_down(isl::val(ctx(), v));
 }
 
-isl::union_set union_pw_aff::bind(isl::id id) const
+isl::multi_union_pw_aff union_pw_aff::set_at(int pos, const isl::union_pw_aff &el) const
 {
-  if (!ptr || id.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_union_pw_aff_bind_id(copy(), id.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_union_pw_aff(*this).set_at(pos, el);
 }
 
-isl::union_set union_pw_aff::bind(const std::string &id) const
+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 this->bind(isl::id(ctx(), id));
+  return isl::multi_union_pw_aff(*this).set_range_tuple(id);
 }
 
-isl::union_pw_aff union_pw_aff::coalesce() const
+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__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_pw_aff_coalesce(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->set_range_tuple(isl::id(ctx(), id));
 }
 
-isl::union_set union_pw_aff::domain() const
+unsigned union_pw_aff::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_union_pw_aff_domain(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_union_pw_aff(*this).size();
 }
 
 isl::space union_pw_aff::space() const
@@ -17167,136 +25588,120 @@ isl::space union_pw_aff::get_space() const
   return space();
 }
 
-isl::union_pw_aff union_pw_aff::gist(isl::union_set context) const
+isl::multi_union_pw_aff union_pw_aff::sub(const isl::multi_union_pw_aff &multi2) const
 {
-  if (!ptr || context.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_union_pw_aff_gist(copy(), context.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_union_pw_aff(*this).sub(multi2);
 }
 
-isl::union_pw_aff union_pw_aff::intersect_domain(isl::space space) const
+isl::union_pw_aff union_pw_aff::sub(isl::union_pw_aff upa2) const
 {
-  if (!ptr || space.is_null())
+  if (!ptr || upa2.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_union_pw_aff_intersect_domain_space(copy(), space.release());
+  auto res = isl_union_pw_aff_sub(copy(), upa2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_pw_aff union_pw_aff::intersect_domain(isl::union_set uset) const
+isl::union_pw_multi_aff union_pw_aff::sub(const isl::union_pw_multi_aff &upma2) const
 {
-  if (!ptr || uset.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_union_pw_aff_intersect_domain_union_set(copy(), uset.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_multi_aff(*this).sub(upma2);
 }
 
-isl::union_pw_aff union_pw_aff::intersect_domain_wrapped_domain(isl::union_set uset) const
+isl::union_pw_aff union_pw_aff::sub(const isl::aff &upa2) const
 {
-  if (!ptr || uset.is_null())
+  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())
     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_intersect_domain_wrapped_domain(copy(), uset.release());
+  auto res = isl_union_pw_aff_subtract_domain_space(copy(), space.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_pw_aff union_pw_aff::intersect_domain_wrapped_range(isl::union_set uset) const
+isl::union_pw_aff union_pw_aff::subtract_domain(isl::union_set uset) const
 {
   if (!ptr || uset.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_union_pw_aff_intersect_domain_wrapped_range(copy(), uset.release());
+  auto res = isl_union_pw_aff_subtract_domain_union_set(copy(), uset.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_pw_aff union_pw_aff::intersect_params(isl::set set) const
+isl::union_pw_aff_list union_pw_aff::to_list() const
 {
-  if (!ptr || set.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_union_pw_aff_intersect_params(copy(), set.release());
+  auto res = isl_union_pw_aff_to_list(copy());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_pw_aff union_pw_aff::pullback(isl::union_pw_multi_aff upma) const
+isl::multi_union_pw_aff union_pw_aff::union_add(const isl::multi_union_pw_aff &mupa2) const
 {
-  if (!ptr || upma.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_union_pw_aff_pullback_union_pw_multi_aff(copy(), upma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_union_pw_aff(*this).union_add(mupa2);
 }
 
-isl::union_pw_aff union_pw_aff::sub(isl::union_pw_aff upa2) const
+isl::union_pw_aff union_pw_aff::union_add(isl::union_pw_aff upa2) const
 {
   if (!ptr || upa2.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_union_pw_aff_sub(copy(), upa2.release());
+  auto res = isl_union_pw_aff_union_add(copy(), upa2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::union_pw_aff union_pw_aff::subtract_domain(isl::space space) const
+isl::union_pw_multi_aff union_pw_aff::union_add(const isl::union_pw_multi_aff &upma2) const
 {
-  if (!ptr || space.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_union_pw_aff_subtract_domain_space(copy(), space.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_multi_aff(*this).union_add(upma2);
 }
 
-isl::union_pw_aff union_pw_aff::subtract_domain(isl::union_set uset) const
+isl::union_pw_aff union_pw_aff::union_add(const isl::aff &upa2) const
 {
-  if (!ptr || uset.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_union_pw_aff_subtract_domain_union_set(copy(), uset.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->union_add(isl::union_pw_aff(upa2));
 }
 
-isl::union_pw_aff union_pw_aff::union_add(isl::union_pw_aff upa2) const
+isl::union_pw_aff union_pw_aff::union_add(const isl::pw_aff &upa2) const
 {
-  if (!ptr || upa2.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_union_pw_aff_union_add(copy(), upa2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->union_add(isl::union_pw_aff(upa2));
 }
 
 inline std::ostream &operator<<(std::ostream &os, const union_pw_aff &obj)
@@ -17370,6 +25775,16 @@ union_pw_aff_list::union_pw_aff_list(isl::union_pw_aff el)
   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 @@ isl::union_pw_aff_list union_pw_aff_list::add(isl::union_pw_aff el) const
   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 @@ void union_pw_aff_list::foreach(const std::function<void(isl::union_pw_aff)> &fn
   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,13 +26085,37 @@ isl::union_pw_multi_aff union_pw_multi_aff::apply(isl::union_pw_multi_aff upma2)
   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)
     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_pw_multi_aff(copy());
+  auto res = isl_union_pw_multi_aff_as_pw_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  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);
@@ -17740,23 +26179,6 @@ isl::union_pw_multi_aff union_pw_multi_aff::flat_range_product(isl::union_pw_mul
   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 @@ isl::union_pw_multi_aff union_pw_multi_aff::pullback(isl::union_pw_multi_aff upm
   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 @@ isl::union_pw_multi_aff union_pw_multi_aff::range_product(isl::union_pw_multi_af
   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 @@ isl::union_set union_set::apply(isl::union_map umap) const
   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 @@ void union_set::foreach_set(const std::function<void(isl::set)> &fn) const
   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 @@ isl::point union_set::sample_point() const
   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 @@ isl::union_set union_set::subtract(isl::union_set uset2) const
   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 @@ union_set_list::union_set_list(isl::union_set el)
   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 @@ isl::union_set_list union_set_list::add(isl::union_set el) const
   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 @@ void union_set_list::foreach(const std::function<void(isl::union_set)> &fn) cons
   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 @@ int val::cmp_si(long i) const
   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 @@ bool val::ge(long v2) const
   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 @@ isl::val val::negone(isl::ctx ctx)
   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 @@ isl::val val::sub(long v2) const
   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 @@ val_list::val_list(isl::val el)
   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 @@ isl::val_list val_list::add(long el) const
   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 @@ void val_list::foreach(const std::function<void(isl::val)> &fn) const
   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/polly/lib/External/isl/include/isl/id.h b/polly/lib/External/isl/include/isl/id.h
index 956b962ef1b20..3e71cb007cd60 100644
--- a/polly/lib/External/isl/include/isl/id.h
+++ b/polly/lib/External/isl/include/isl/id.h
@@ -13,6 +13,7 @@ extern "C" {
 #endif
 
 ISL_DECLARE_EXPORTED_LIST_FN(id)
+ISL_DECLARE_EXPORTED_LIST_FN_READ(id)
 
 ISL_DECLARE_MULTI(id)
 

diff  --git a/polly/lib/External/isl/include/isl/list.h b/polly/lib/External/isl/include/isl/list.h
index 47fcef71e97c4..3d8dabedf05cf 100644
--- a/polly/lib/External/isl/include/isl/list.h
+++ b/polly/lib/External/isl/include/isl/list.h
@@ -27,6 +27,8 @@ typedef struct isl_##EL##_list isl_##EL##_list;
 	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 @@ void isl_##EL##_list_dump(__isl_keep isl_##EL##_list *list);
 	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/polly/lib/External/isl/include/isl/map.h b/polly/lib/External/isl/include/isl/map.h
index 7fdd3563593f6..ede0463800dd9 100644
--- a/polly/lib/External/isl/include/isl/map.h
+++ b/polly/lib/External/isl/include/isl/map.h
@@ -34,6 +34,10 @@ isl_size isl_basic_map_total_dim(__isl_keep const isl_basic_map *bmap);
 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 @@ isl_bool isl_map_has_dim_id(__isl_keep isl_map *map,
 	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_bool isl_basic_map_is_strict_subset(__isl_keep isl_basic_map *bmap1,
 
 __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_map *isl_map_gist_basic_map(__isl_take isl_map *map,
 __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_give isl_basic_map *isl_basic_map_from_aff_list(
 	__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/polly/lib/External/isl/include/isl/map_type.h b/polly/lib/External/isl/include/isl/map_type.h
index 7c30056f71ef8..880258465d652 100644
--- a/polly/lib/External/isl/include/isl/map_type.h
+++ b/polly/lib/External/isl/include/isl/map_type.h
@@ -13,7 +13,7 @@ typedef struct isl_basic_map isl_basic_map;
 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/polly/lib/External/isl/include/isl/multi.h b/polly/lib/External/isl/include/isl/multi.h
index 52bac4a135edb..3c39778da736e 100644
--- a/polly/lib/External/isl/include/isl/multi.h
+++ b/polly/lib/External/isl/include/isl/multi.h
@@ -24,6 +24,9 @@ __isl_give isl_##BASE##_list *isl_multi_##BASE##_get_list(		\
 __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_give isl_multi_##BASE *isl_multi_##BASE##_identity(		\
 __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 @@ __isl_give isl_multi_##BASE *isl_multi_##BASE##_add_constant_multi_val(	\
 #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 @@ __isl_give isl_multi_##BASE *isl_multi_##BASE##_set_dim_id(		\
 #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/polly/lib/External/isl/include/isl/polynomial.h b/polly/lib/External/isl/include/isl/polynomial.h
index 0be4f0af917ab..2d5baaf815ec9 100644
--- a/polly/lib/External/isl/include/isl/polynomial.h
+++ b/polly/lib/External/isl/include/isl/polynomial.h
@@ -535,6 +535,8 @@ isl_bool isl_union_pw_qpolynomial_plain_is_equal(
 	__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_bool isl_union_pw_qpolynomial_fold_plain_is_equal(
 	__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/polly/lib/External/isl/include/isl/set.h b/polly/lib/External/isl/include/isl/set.h
index 2fc8e5f9c0cf7..4b66b82e6f410 100644
--- a/polly/lib/External/isl/include/isl/set.h
+++ b/polly/lib/External/isl/include/isl/set.h
@@ -34,6 +34,8 @@ isl_size isl_basic_set_dim(__isl_keep isl_basic_set *bset,
 
 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_export
 __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_give isl_val *isl_set_count_val(__isl_keep isl_set *set);
 
 __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_constraint_matrices(
 __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/polly/lib/External/isl/include/isl/space.h b/polly/lib/External/isl/include/isl/space.h
index 6f3da5b62cac0..f3e1d8a15b266 100644
--- a/polly/lib/External/isl/include/isl/space.h
+++ b/polly/lib/External/isl/include/isl/space.h
@@ -34,6 +34,7 @@ isl_bool isl_space_is_params(__isl_keep isl_space *space);
 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 @@ isl_bool isl_space_has_tuple_name(__isl_keep isl_space *space,
 	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/polly/lib/External/isl/include/isl/typed_cpp.h b/polly/lib/External/isl/include/isl/typed_cpp.h
new file mode 100644
index 0000000000000..df39c8ea5a943
--- /dev/null
+++ b/polly/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/polly/lib/External/isl/include/isl/union_map.h b/polly/lib/External/isl/include/isl/union_map.h
index 4cae61142f764..c630dc0807908 100644
--- a/polly/lib/External/isl/include/isl/union_map.h
+++ b/polly/lib/External/isl/include/isl/union_map.h
@@ -23,6 +23,8 @@ __isl_give isl_id *isl_union_map_get_dim_id(__isl_keep isl_union_map *umap,
 __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_size isl_union_map_n_map(__isl_keep isl_union_map *umap);
 __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_give isl_map *isl_union_map_extract_map(__isl_keep isl_union_map *umap,
 	__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/polly/lib/External/isl/include/isl/union_set.h b/polly/lib/External/isl/include/isl/union_set.h
index 8531da869bcfd..35ae11c994385 100644
--- a/polly/lib/External/isl/include/isl/union_set.h
+++ b/polly/lib/External/isl/include/isl/union_set.h
@@ -14,6 +14,8 @@ isl_size isl_union_set_dim(__isl_keep isl_union_set *uset,
 __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_give isl_set *isl_union_set_extract_set(__isl_keep isl_union_set *uset,
 	__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 @@ __isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p,
 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/polly/lib/External/isl/include/isl/val.h b/polly/lib/External/isl/include/isl/val.h
index f09252c47264f..942207db91674 100644
--- a/polly/lib/External/isl/include/isl/val.h
+++ b/polly/lib/External/isl/include/isl/val.h
@@ -170,6 +170,7 @@ void isl_multi_val_dump(__isl_keep isl_multi_val *mv);
 __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/polly/lib/External/isl/install-sh b/polly/lib/External/isl/install-sh
index 8175c640fe628..ec298b5374027 100755
--- a/polly/lib/External/isl/install-sh
+++ b/polly/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 @@ posix_mkdir=
 # 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 @@ Options:
      --version  display version info and exit.
 
   -c            (ignored)
-  -C            install only if 
diff erent (preserve the last data modification time)
+  -C            install only if 
diff erent (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 at gnu.org.
+Automake home page: https://www.gnu.org/software/automake/
 "
 
 while test $# -ne 0; do
@@ -137,8 +152,13 @@ while test $# -ne 0; do
     -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 @@ do
     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 @@ do
   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 @@ do
         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-$$
-
-            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-*) 
diff erent_mode=700;;
-                     d????-?--*) 
diff erent_mode=755;;
-                     *) false;;
-                   esac &&
-                   $mkdirprog -m$
diff erent_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;;
+	# 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
+
+	# 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-*) 
diff erent_mode=700;;
+		 d????-?--*) 
diff erent_mode=755;;
+		 *) false;;
+	       esac &&
+	       $mkdirprog -m$
diff erent_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 @@ do
     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 @@ do
           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 @@ do
     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 @@ do
     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 @@ do
         # 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/polly/lib/External/isl/interface/Makefile.am b/polly/lib/External/isl/interface/Makefile.am
index 58bd0e60e805b..702f9a4854f2d 100644
--- a/polly/lib/External/isl/interface/Makefile.am
+++ b/polly/lib/External/isl/interface/Makefile.am
@@ -17,6 +17,11 @@ extract_interface_SOURCES = \
 	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/polly/lib/External/isl/interface/Makefile.in b/polly/lib/External/isl/interface/Makefile.in
index 4b4ce9995608d..93c6371d2b3a3 100644
--- a/polly/lib/External/isl/interface/Makefile.in
+++ b/polly/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 @@ host_triplet = @host@
 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 @@ am_extract_interface_OBJECTS = extract_interface-generator.$(OBJEXT) \
 	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 @@ am__depfiles_remade = ./$(DEPDIR)/extract_interface-cpp.Po \
 	./$(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 @@ am__can_run_installinfo = \
     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 @@ am__post_remove_distdir = $(am__remove_distdir)
 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 @@ EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
+HAVE_CXX11 = @HAVE_CXX11@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -365,7 +375,6 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -390,6 +399,11 @@ extract_interface_SOURCES = \
 	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 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/extract_interface-cpp_conversion.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/extract_interface-extract_interface.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/extract_interface-generator.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/extract_interface-plain_cpp.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/extract_interface-python.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/extract_interface-template_cpp.Po at am__quote@ # am--include-marker
 
 $(am__depfiles_remade):
 	@$(MKDIR_P) $(@D)
@@ -557,6 +573,34 @@ extract_interface-cpp_conversion.obj: cpp_conversion.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at 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
+ at 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
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-plain_cpp.Tpo $(DEPDIR)/extract_interface-plain_cpp.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='plain_cpp.cc' object='extract_interface-plain_cpp.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at 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
+ at 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`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-plain_cpp.Tpo $(DEPDIR)/extract_interface-plain_cpp.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='plain_cpp.cc' object='extract_interface-plain_cpp.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at 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
+ at 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
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-template_cpp.Tpo $(DEPDIR)/extract_interface-template_cpp.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='template_cpp.cc' object='extract_interface-template_cpp.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at 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
+ at 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`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-template_cpp.Tpo $(DEPDIR)/extract_interface-template_cpp.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='template_cpp.cc' object='extract_interface-template_cpp.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at 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 @@ dist-xz: distdir
 	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 @@ distcheck: dist
 	  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: dist
 	    $(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 @@ distclean: distclean-am
 	-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 @@ maintainer-clean: maintainer-clean-am
 	-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 @@ uninstall-am:
 	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/polly/lib/External/isl/interface/aclocal.m4 b/polly/lib/External/isl/interface/aclocal.m4
index e3797c0babbf7..f7f49e474958a 100644
--- a/polly/lib/External/isl/interface/aclocal.m4
+++ b/polly/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 @@ You have another version of autoconf.  It may work, but is not guaranteed to.
 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 at 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 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
 [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 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # 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_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 # 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 @@ AC_CONFIG_COMMANDS_PRE(
 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 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
 
 # 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 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
   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 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 
 # 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 @@ for _am_header in $config_headers :; do
 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 @@ if test x"${install_sh+set}" != xset; then
 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 @@ AC_SUBST([am__leading_dot])])
 
 # 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 @@ AC_SUBST([am__quote])])
 
 # 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_DEFUN([AM_MISSING_HAS_RUN],
 [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 @@ fi
 
 # 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_SET_OPTIONS],
 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 @@ AC_LANG_POP([C])])
 # 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 @@ AC_DEFUN([AM_RUN_LOG],
 
 # 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 @@ AC_CONFIG_COMMANDS_PRE(
 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 @@ AC_SUBST([AM_BACKSLASH])dnl
 _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 @@ fi
 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 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # 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__tar])
 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/polly/lib/External/isl/interface/compile b/polly/lib/External/isl/interface/compile
old mode 100644
new mode 100755
index 99e50524b3bad..23fcba011321a
--- a/polly/lib/External/isl/interface/compile
+++ b/polly/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 at cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -53,7 +53,7 @@ func_file_conv ()
 	  MINGW*)
 	    file_conv=mingw
 	    ;;
-	  CYGWIN*)
+	  CYGWIN* | MSYS*)
 	    file_conv=cygwin
 	    ;;
 	  *)
@@ -67,7 +67,7 @@ func_file_conv ()
 	mingw/*)
 	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
 	  ;;
-	cygwin/*)
+	cygwin/* | msys/*)
 	  file=`cygpath -m "$file" || echo "$file"`
 	  ;;
 	wine/*)

diff  --git a/polly/lib/External/isl/interface/config.guess b/polly/lib/External/isl/interface/config.guess
old mode 100644
new mode 100755
index f50dcdb6de2af..0fc11edb2d12e
--- a/polly/lib/External/isl/interface/config.guess
+++ b/polly/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 @@ timestamp='2018-02-24'
 # Please send patches to <config-patches at gnu.org>.
 
 
-me=`echo "$0" | sed -e 's,.*/,,'`
+me=$(echo "$0" | sed -e 's,.*/,,')
 
 usage="\
 Usage: $0 [OPTION]
@@ -50,7 +50,7 @@ version="\
 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 @@ if test $# != 0; then
   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 @@ trap 'exit 1' 1 2 15
 
 # 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 at 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 @@ Linux|GNU|GNU/*)
 	# 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 @@ Linux|GNU|GNU/*)
 	#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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	# 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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 		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:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 		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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
     *: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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
     *: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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	# 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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	exit ;;
     Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
 	# akee at 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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 		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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	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 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	}
 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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 			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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 			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 @@ EOF
 		    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 @@ EOF
 	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 @@ EOF
 	  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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
     *: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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
     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 @@ EOF
     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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
     *: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 @@ EOF
 	# "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 @@ EOF
 	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 @@ EOF
 	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 @@ EOF
     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 @@ copies of config.guess and config.sub with the latest versions from:
   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 at gnu.org to
@@ -1449,31 +1654,32 @@ provide the necessary information to handle your system.
 
 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/polly/lib/External/isl/interface/config.sub b/polly/lib/External/isl/interface/config.sub
old mode 100644
new mode 100755
index 1d8e98bcee23a..c874b7a9df8a9
--- a/polly/lib/External/isl/interface/config.sub
+++ b/polly/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 @@ timestamp='2018-02-22'
 #	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 @@ Report bugs and patches to <config-patches at gnu.org>."
 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 @@ while test $# -gt 0 ; do
     - )	# 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 @@ case $# in
     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.
-		;;
-	-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
-		;;
-	-bluegene*)
-		os=-cnk
-		;;
-	-sim | -cisco | -oki | -wec | -winbond)
-		os=
-		basic_machine=$1
-		;;
-	-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
+# Separate into logical components for further validation
+case $1 in
+	*-*-*-*-*)
+		echo Invalid configuration \`"$1"\': more than four components >&2
+		exit 1
 		;;
-	-lynx*)
-		os=-lynxos
+	*-*-*-*)
+		basic_machine=$field1-$field2
+		basic_os=$field3-$field4
 		;;
-	-ptx*)
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
+	*-*-*)
+		# 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
 		;;
-	-psos*)
-		os=-psos
+	*-*)
+		# 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
 		;;
-	-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
-		;;
-	c54x)
-		basic_machine=tic54x-unknown
-		;;
-	c55x)
-		basic_machine=tic55x-unknown
-		;;
-	c6x)
-		basic_machine=tic6x-unknown
-		;;
-	leon|leon[3-9])
-		basic_machine=sparc-$basic_machine
-		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
-		basic_machine=$basic_machine-unknown
-		os=-none
+	# 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
 		;;
-	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
+	op50n)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-	ms1)
-		basic_machine=mt-unknown
+	op60c)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-
-	strongarm | thumb | xscale)
-		basic_machine=arm-unknown
+	ibm*)
+		cpu=i370
+		vendor=ibm
 		;;
-	xgate)
-		basic_machine=$basic_machine-unknown
-		os=-none
+	orion105)
+		cpu=clipper
+		vendor=highlevel
 		;;
-	xscaleeb)
-		basic_machine=armeb-unknown
+	mac | mpw | mac-mpw)
+		cpu=m68k
+		vendor=apple
 		;;
-
-	xscaleel)
-		basic_machine=armel-unknown
+	pmac | pmac-mpw)
+		cpu=powerpc
+		vendor=apple
 		;;
 
-	# 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
-		;;
-	# 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
+		cpu=m68000
+		vendor=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
+		cpu=we32k
+		vendor=att
 		;;
 	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
+		cpu=powerpc
+		vendor=ibm
+		basic_os=cnk
 		;;
 	decsystem10* | dec10*)
-		basic_machine=pdp10-dec
-		os=-tops10
+		cpu=pdp10
+		vendor=dec
+		basic_os=tops10
 		;;
 	decsystem20* | dec20*)
-		basic_machine=pdp10-dec
-		os=-tops20
+		cpu=pdp10
+		vendor=dec
+		basic_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
+		cpu=m68k
+		vendor=motorola
 		;;
 	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
+		cpu=m68k
+		vendor=bull
+		basic_os=sysv3
 		;;
 	encore | umax | mmax)
-		basic_machine=ns32k-encore
+		cpu=ns32k
+		vendor=encore
 		;;
-	es1800 | OSE68k | ose68k | ose | OSE)
-		basic_machine=m68k-ericsson
-		os=-ose
+	elxsi)
+		cpu=elxsi
+		vendor=elxsi
+		basic_os=${basic_os:-bsd}
 		;;
 	fx2800)
-		basic_machine=i860-alliant
+		cpu=i860
+		vendor=alliant
 		;;
 	genix)
-		basic_machine=ns32k-ns
-		;;
-	gmicro)
-		basic_machine=tron-gmicro
-		os=-sysv
-		;;
-	go32)
-		basic_machine=i386-pc
-		os=-go32
+		cpu=ns32k
+		vendor=ns
 		;;
 	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
+		cpu=hppa1.1
+		vendor=hitachi
+		basic_os=hiuxwe2
 		;;
 	hp3k9[0-9][0-9] | hp9[0-9][0-9])
-		basic_machine=hppa1.0-hp
+		cpu=hppa1.0
+		vendor=hp
 		;;
 	hp9k2[0-9][0-9] | hp9k31[0-9])
-		basic_machine=m68000-hp
+		cpu=m68000
+		vendor=hp
 		;;
 	hp9k3[2-9][0-9])
-		basic_machine=m68k-hp
+		cpu=m68k
+		vendor=hp
 		;;
 	hp9k6[0-9][0-9] | hp6[0-9][0-9])
-		basic_machine=hppa1.0-hp
+		cpu=hppa1.0
+		vendor=hp
 		;;
 	hp9k7[0-79][0-9] | hp7[0-79][0-9])
-		basic_machine=hppa1.1-hp
+		cpu=hppa1.1
+		vendor=hp
 		;;
 	hp9k78[0-9] | hp78[0-9])
 		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-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
-		basic_machine=hppa1.1-hp
+		cpu=hppa1.1
+		vendor=hp
 		;;
 	hp9k8[0-9][13679] | hp8[0-9][13679])
-		basic_machine=hppa1.1-hp
+		cpu=hppa1.1
+		vendor=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
+		cpu=hppa1.0
+		vendor=hp
 		;;
 	i*86v32)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv32
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=sysv32
 		;;
 	i*86v4*)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv4
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=sysv4
 		;;
 	i*86v)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=sysv
 		;;
 	i*86sol2)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-solaris2
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=solaris2
 		;;
-	i386mach)
-		basic_machine=i386-mach
-		os=-mach
-		;;
-	vsta)
-		basic_machine=i386-unknown
-		os=-vsta
+	j90 | j90-cray)
+		cpu=j90
+		vendor=cray
+		basic_os=${basic_os:-unicos}
 		;;
 	iris | iris4d)
-		basic_machine=mips-sgi
-		case $os in
-		    -irix*)
+		cpu=mips
+		vendor=sgi
+		case $basic_os in
+		    irix*)
 			;;
 		    *)
-			os=-irix4
+			basic_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
+		cpu=m68000
+		vendor=convergent
 		;;
-	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
+	*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		cpu=m68k
+		vendor=atari
+		basic_os=mint
 		;;
 	news-3600 | risc-news)
-		basic_machine=mips-sony
-		os=-newsos
-		;;
-	necv70)
-		basic_machine=v70-nec
-		os=-sysv
+		cpu=mips
+		vendor=sony
+		basic_os=newsos
 		;;
 	next | m*-next)
-		basic_machine=m68k-next
-		case $os in
-		    -nextstep* )
+		cpu=m68k
+		vendor=next
+		case $basic_os in
+		    openstep*)
+		        ;;
+		    nextstep*)
 			;;
-		    -ns2*)
-		      os=-nextstep2
+		    ns2*)
+		      basic_os=nextstep2
 			;;
 		    *)
-		      os=-nextstep3
+		      basic_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
+		cpu=np1
+		vendor=gould
 		;;
 	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
+		cpu=hppa1.1
+		vendor=oki
+		basic_os=proelf
 		;;
 	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
+		cpu=hppa1.1
+		vendor=hitachi
+		basic_os=hiuxwe2
 		;;
 	pbd)
-		basic_machine=sparc-tti
+		cpu=sparc
+		vendor=tti
 		;;
 	pbb)
-		basic_machine=m68k-tti
-		;;
-	pc532 | pc532-*)
-		basic_machine=ns32k-pc532
-		;;
-	pc98)
-		basic_machine=i386-pc
-		;;
-	pc98-*)
-		basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	pentium | p5 | k5 | k6 | nexgen | viac3)
-		basic_machine=i586-pc
-		;;
-	pentiumpro | p6 | 6x86 | athlon | athlon_*)
-		basic_machine=i686-pc
+		cpu=m68k
+		vendor=tti
 		;;
-	pentiumii | pentium2 | pentiumiii | pentium3)
-		basic_machine=i686-pc
-		;;
-	pentium4)
-		basic_machine=i786-pc
-		;;
-	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-		basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	pentiumpro-* | p6-* | 6x86-* | athlon-*)
-		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	pentium4-*)
-		basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	pc532)
+		cpu=ns32k
+		vendor=pc532
 		;;
 	pn)
-		basic_machine=pn-gould
-		;;
-	power)	basic_machine=power-ibm
+		cpu=pn
+		vendor=gould
 		;;
-	ppc | ppcbe)	basic_machine=powerpc-unknown
-		;;
-	ppc-* | ppcbe-*)
-		basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	ppcle | powerpclittle)
-		basic_machine=powerpcle-unknown
-		;;
-	ppcle-* | powerpclittle-*)
-		basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	power)
+		cpu=power
+		vendor=ibm
 		;;
-	ppc64)	basic_machine=powerpc64-unknown
+	ps2)
+		cpu=i386
+		vendor=ibm
 		;;
-	ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	rm[46]00)
+		cpu=mips
+		vendor=siemens
 		;;
-	ppc64le | powerpc64little)
-		basic_machine=powerpc64le-unknown
+	rtpc | rtpc-*)
+		cpu=romp
+		vendor=ibm
 		;;
-	ppc64le-* | powerpc64little-*)
-		basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	sde)
+		cpu=mipsisa32
+		vendor=sde
+		basic_os=${basic_os:-elf}
 		;;
-	ps2)
-		basic_machine=i386-ibm
+	simso-wrs)
+		cpu=sparclite
+		vendor=wrs
+		basic_os=vxworks
 		;;
-	pw32)
-		basic_machine=i586-unknown
-		os=-pw32
+	tower | tower-32)
+		cpu=m68k
+		vendor=ncr
 		;;
-	rdos | rdos64)
-		basic_machine=x86_64-pc
-		os=-rdos
+	vpp*|vx|vx-*)
+		cpu=f301
+		vendor=fujitsu
 		;;
-	rdos32)
-		basic_machine=i386-pc
-		os=-rdos
+	w65)
+		cpu=w65
+		vendor=wdc
 		;;
-	rom68k)
-		basic_machine=m68k-rom68k
-		os=-coff
+	w89k-*)
+		cpu=hppa1.1
+		vendor=winbond
+		basic_os=proelf
 		;;
-	rm[46]00)
-		basic_machine=mips-siemens
+	none)
+		cpu=none
+		vendor=none
 		;;
-	rtpc | rtpc-*)
-		basic_machine=romp-ibm
+	leon|leon[3-9])
+		cpu=sparc
+		vendor=$basic_machine
 		;;
-	s390 | s390-*)
-		basic_machine=s390-ibm
+	leon-*|leon[3-9]-*)
+		cpu=sparc
+		vendor=$(echo "$basic_machine" | sed 's/-.*//')
 		;;
-	s390x | s390x-*)
-		basic_machine=s390x-ibm
+
+	*-*)
+		# shellcheck disable=SC2162
+		IFS="-" read cpu vendor <<EOF
+$basic_machine
+EOF
 		;;
-	sa29200)
-		basic_machine=a29k-amd
-		os=-udi
+	# 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)
+		cpu=$basic_machine
+		vendor=pc
 		;;
-	sb1)
-		basic_machine=mipsisa64sb1-unknown
+	# 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)
+		cpu=i386
+		vendor=pc
 		;;
-	sb1el)
-		basic_machine=mipsisa64sb1el-unknown
+	x64 | amd64)
+		cpu=x86_64
+		vendor=pc
 		;;
-	sde)
-		basic_machine=mipsisa32-sde
-		os=-elf
+	# Recognize the basic CPU types without company name.
+	*)
+		cpu=$basic_machine
+		vendor=unknown
 		;;
-	sei)
-		basic_machine=mips-sei
-		os=-seiux
+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}
 		;;
-	sequent)
-		basic_machine=i386-sequent
+	c90-unknown | c90-cray)
+		vendor=cray
+		basic_os=${Basic_os:-unicos}
 		;;
-	sh5el)
-		basic_machine=sh5le-unknown
+	fx80-unknown)
+		vendor=alliant
 		;;
-	simso-wrs)
-		basic_machine=sparclite-wrs
-		os=-vxworks
+	romp-unknown)
+		vendor=ibm
 		;;
-	sps7)
-		basic_machine=m68k-bull
-		os=-sysv2
+	mmix-unknown)
+		vendor=knuth
 		;;
-	spur)
-		basic_machine=spur-unknown
+	microblaze-unknown | microblazeel-unknown)
+		vendor=xilinx
 		;;
-	st2000)
-		basic_machine=m68k-tandem
+	rs6000-unknown)
+		vendor=ibm
 		;;
-	stratus)
-		basic_machine=i860-stratus
-		os=-sysv4
+	vax-unknown)
+		vendor=dec
 		;;
-	strongarm-* | thumb-*)
-		basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	pdp11-unknown)
+		vendor=dec
 		;;
-	sun2)
-		basic_machine=m68000-sun
+	we32k-unknown)
+		vendor=att
 		;;
-	sun2os3)
-		basic_machine=m68000-sun
-		os=-sunos3
+	cydra-unknown)
+		vendor=cydrome
 		;;
-	sun2os4)
-		basic_machine=m68000-sun
-		os=-sunos4
+	i370-ibm*)
+		vendor=ibm
 		;;
-	sun3os3)
-		basic_machine=m68k-sun
-		os=-sunos3
+	orion-unknown)
+		vendor=highlevel
 		;;
-	sun3os4)
-		basic_machine=m68k-sun
-		os=-sunos4
+	xps-unknown | xps100-unknown)
+		cpu=xps100
+		vendor=honeywell
 		;;
-	sun4os3)
-		basic_machine=sparc-sun
-		os=-sunos3
+
+	# Here we normalize CPU types with a missing or matching vendor
+	dpx20-unknown | dpx20-bull)
+		cpu=rs6000
+		vendor=bull
+		basic_os=${basic_os:-bosx}
 		;;
-	sun4os4)
-		basic_machine=sparc-sun
-		os=-sunos4
+
+	# Here we normalize CPU types irrespective of the vendor
+	amd64-*)
+		cpu=x86_64
 		;;
-	sun4sol2)
-		basic_machine=sparc-sun
-		os=-solaris2
+	blackfin-*)
+		cpu=bfin
+		basic_os=linux
 		;;
-	sun3 | sun3-*)
-		basic_machine=m68k-sun
+	c54x-*)
+		cpu=tic54x
 		;;
-	sun4)
-		basic_machine=sparc-sun
+	c55x-*)
+		cpu=tic55x
 		;;
-	sun386 | sun386i | roadrunner)
-		basic_machine=i386-sun
+	c6x-*)
+		cpu=tic6x
 		;;
-	sv1)
-		basic_machine=sv1-cray
-		os=-unicos
+	e500v[12]-*)
+		cpu=powerpc
+		basic_os=${basic_os}"spe"
 		;;
-	symmetry)
-		basic_machine=i386-sequent
-		os=-dynix
+	mips3*-*)
+		cpu=mips64
 		;;
-	t3e)
-		basic_machine=alphaev5-cray
-		os=-unicos
+	ms1-*)
+		cpu=mt
 		;;
-	t90)
-		basic_machine=t90-cray
-		os=-unicos
+	m68knommu-*)
+		cpu=m68k
+		basic_os=linux
 		;;
-	tile*)
-		basic_machine=$basic_machine-unknown
-		os=-linux-gnu
+	m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
+		cpu=s12z
 		;;
-	tx39)
-		basic_machine=mipstx39-unknown
+	openrisc-*)
+		cpu=or32
 		;;
-	tx39el)
-		basic_machine=mipstx39el-unknown
+	parisc-*)
+		cpu=hppa
+		basic_os=linux
 		;;
-	toad1)
-		basic_machine=pdp10-xkl
-		os=-tops20
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		cpu=i586
 		;;
-	tower | tower-32)
-		basic_machine=m68k-ncr
+	pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
+		cpu=i686
 		;;
-	tpf)
-		basic_machine=s390x-ibm
-		os=-tpf
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		cpu=i686
 		;;
-	udi29k)
-		basic_machine=a29k-amd
-		os=-udi
+	pentium4-*)
+		cpu=i786
 		;;
-	ultra3)
-		basic_machine=a29k-nyu
-		os=-sym1
+	pc98-*)
+		cpu=i386
 		;;
-	v810 | necv810)
-		basic_machine=v810-nec
-		os=-none
+	ppc-* | ppcbe-*)
+		cpu=powerpc
 		;;
-	vaxv)
-		basic_machine=vax-dec
-		os=-sysv
+	ppcle-* | powerpclittle-*)
+		cpu=powerpcle
 		;;
-	vms)
-		basic_machine=vax-dec
-		os=-vms
+	ppc64-*)
+		cpu=powerpc64
 		;;
-	vpp*|vx|vx-*)
-		basic_machine=f301-fujitsu
+	ppc64le-* | powerpc64little-*)
+		cpu=powerpc64le
 		;;
-	vxworks960)
-		basic_machine=i960-wrs
-		os=-vxworks
+	sb1-*)
+		cpu=mipsisa64sb1
 		;;
-	vxworks68)
-		basic_machine=m68k-wrs
-		os=-vxworks
+	sb1el-*)
+		cpu=mipsisa64sb1el
 		;;
-	vxworks29k)
-		basic_machine=a29k-wrs
-		os=-vxworks
+	sh5e[lb]-*)
+		cpu=$(echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/')
 		;;
-	w65*)
-		basic_machine=w65-wdc
-		os=-none
+	spur-*)
+		cpu=spur
 		;;
-	w89k-*)
-		basic_machine=hppa1.1-winbond
-		os=-proelf
+	strongarm-* | thumb-*)
+		cpu=arm
 		;;
-	x64)
-		basic_machine=x86_64-pc
+	tx39-*)
+		cpu=mipstx39
 		;;
-	xbox)
-		basic_machine=i686-pc
-		os=-mingw32
+	tx39el-*)
+		cpu=mipstx39el
 		;;
-	xps | xps100)
-		basic_machine=xps100-honeywell
+	x64-*)
+		cpu=x86_64
 		;;
 	xscale-* | xscalee[bl]-*)
-		basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
+		cpu=$(echo "$cpu" | sed 's/^xscale/arm/')
 		;;
-	ymp)
-		basic_machine=ymp-cray
-		os=-unicos
-		;;
-	none)
-		basic_machine=none-none
-		os=-none
+	arm64-*)
+		cpu=aarch64
 		;;
 
-# 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
+	# Recognize the canonical CPU Types that limit and/or modify the
+	# company names they are paired with.
+	cr16-*)
+		basic_os=${basic_os:-elf}
 		;;
-	op50n)
-		basic_machine=hppa1.1-oki
+	crisv32-* | etraxfs*-*)
+		cpu=crisv32
+		vendor=axis
 		;;
-	op60c)
-		basic_machine=hppa1.1-oki
+	cris-* | etrax*-*)
+		cpu=cris
+		vendor=axis
 		;;
-	romp)
-		basic_machine=romp-ibm
+	crx-*)
+		basic_os=${basic_os:-elf}
 		;;
-	mmix)
-		basic_machine=mmix-knuth
-		;;
-	rs6000)
-		basic_machine=rs6000-ibm
-		;;
-	vax)
-		basic_machine=vax-dec
-		;;
-	pdp11)
-		basic_machine=pdp11-dec
-		;;
-	we32k)
-		basic_machine=we32k-att
-		;;
-	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
-		basic_machine=sh-unknown
+	neo-tandem)
+		cpu=neo
+		vendor=tandem
 		;;
-	cydra)
-		basic_machine=cydra-cydrome
+	nse-tandem)
+		cpu=nse
+		vendor=tandem
 		;;
-	orion)
-		basic_machine=orion-highlevel
+	nsr-tandem)
+		cpu=nsr
+		vendor=tandem
 		;;
-	orion105)
-		basic_machine=clipper-highlevel
+	nsv-tandem)
+		cpu=nsv
+		vendor=tandem
 		;;
-	mac | mpw | mac-mpw)
-		basic_machine=m68k-apple
+	nsx-tandem)
+		cpu=nsx
+		vendor=tandem
 		;;
-	pmac | pmac-mpw)
-		basic_machine=powerpc-apple
+	mipsallegrexel-sony)
+		cpu=mipsallegrexel
+		vendor=sony
 		;;
-	*-unknown)
-		# Make sure to match an already-canonicalized machine name.
+	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 @@ esac
 
 # 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 
diff erent 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.
-		;;
-	-qnx*)
-		case $basic_machine in
-		    x86-* | i*86-*)
-			;;
-		    *)
-			os=-nto$os
-			;;
-		esac
+	# Some version numbers need modification
+	chorusos*)
+		os=chorusos
 		;;
-	-nto-qnx*)
+	isc)
+		os=isc2.2
 		;;
-	-nto*)
-		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+	sco6)
+		os=sco5v6
 		;;
-	-sim | -xray | -os68k* | -v88r* \
-	      | -windows* | -osx | -abug | -netware* | -os9* \
-	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+	sco5)
+		os=sco3.2v5
 		;;
-	-mac*)
-		os=`echo "$os" | sed -e 's|mac|macos|'`
+	sco4)
+		os=sco3.2v4
 		;;
-	-linux-dietlibc)
-		os=-linux-dietlibc
+	sco3.2.[4-9]*)
+		os=$(echo $os | sed -e 's/sco3.2./sco3.2v/')
 		;;
-	-linux*)
-		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+	sco*v* | scout)
+		# Don't match below
 		;;
-	-sunos5*)
-		os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
+	sco*)
+		os=sco3.2v2
 		;;
-	-sunos6*)
-		os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
+	psos*)
+		os=psos
 		;;
-	-opened*)
-		os=-openedition
+	qnx*)
+		os=qnx
 		;;
-	-os400*)
-		os=-os400
+	hiux*)
+		os=hiuxwe2
 		;;
-	-wince*)
-		os=-wince
+	lynx*178)
+		os=lynxos178
 		;;
-	-utek*)
-		os=-bsd
+	lynx*5)
+		os=lynxos5
 		;;
-	-dynix*)
-		os=-bsd
+	lynxos*)
+		# don't get caught up in next wildcard
 		;;
-	-acis*)
-		os=-aos
+	lynx*)
+		os=lynxos
 		;;
-	-atheos*)
-		os=-atheos
+	mac[0-9]*)
+		os=$(echo "$os" | sed -e 's|mac|macos|')
 		;;
-	-syllable*)
-		os=-syllable
+	opened*)
+		os=openedition
 		;;
-	-386bsd)
-		os=-bsd
+	os400*)
+		os=os400
 		;;
-	-ctix* | -uts*)
-		os=-sysv
+	sunos5*)
+		os=$(echo "$os" | sed -e 's|sunos5|solaris2|')
 		;;
-	-nova*)
-		os=-rtmk-nova
+	sunos6*)
+		os=$(echo "$os" | sed -e 's|sunos6|solaris3|')
 		;;
-	-ns2)
-		os=-nextstep2
+	wince*)
+		os=wince
 		;;
-	-nsk*)
-		os=-nsk
+	utek*)
+		os=bsd
 		;;
-	# Preserve the version number of sinix5.
-	-sinix5.*)
-		os=`echo $os | sed -e 's|sinix|sysv|'`
+	dynix*)
+		os=bsd
+		;;
+	acis*)
+		os=aos
+		;;
+	atheos*)
+		os=atheos
+		;;
+	syllable*)
+		os=syllable
+		;;
+	386bsd)
+		os=bsd
+		;;
+	ctix* | uts*)
+		os=sysv
+		;;
+	nova*)
+		os=rtmk-nova
 		;;
-	-sinix*)
-		os=-sysv4
+	ns2)
+		os=nextstep2
 		;;
-	-tpf*)
-		os=-tpf
+	# Preserve the version number of sinix5.
+	sinix5.*)
+		os=$(echo $os | sed -e 's|sinix|sysv|')
 		;;
-	-triton*)
-		os=-sysv3
+	sinix*)
+		os=sysv4
 		;;
-	-oss*)
-		os=-sysv3
+	tpf*)
+		os=tpf
 		;;
-	-svr4*)
-		os=-sysv4
+	triton*)
+		os=sysv3
 		;;
-	-svr3)
-		os=-sysv3
+	oss*)
+		os=sysv3
 		;;
-	-sysvr4)
-		os=-sysv4
+	svr4*)
+		os=sysv4
 		;;
-	# This must come after -sysvr4.
-	-sysv*)
+	svr3)
+		os=sysv3
 		;;
-	-ose*)
-		os=-ose
+	sysvr4)
+		os=sysv4
 		;;
-	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-		os=-mint
+	ose*)
+		os=ose
 		;;
-	-zvmoe)
-		os=-zvmoe
+	*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
+		os=mint
 		;;
-	-dicos*)
-		os=-dicos
+	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 @@ else
 # 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*)
 				vendor=ibm
 				;;
-			-os400*)
+			s390-* | s390x-*)
 				vendor=ibm
 				;;
-			-ptx*)
+			*-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/polly/lib/External/isl/interface/configure b/polly/lib/External/isl/interface/configure
old mode 100644
new mode 100755
index 30e35b199be20..e63e13eb76cdc
--- a/polly/lib/External/isl/interface/configure
+++ b/polly/lib/External/isl/interface/configure
@@ -198,6 +198,7 @@ test -x / || exit 1"
   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 @@ test -x / || exit 1"
     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 @@ DUMPBIN
 LD
 FGREP
 EGREP
-GREP
 SED
 LIBTOOL
+HAVE_CXX11
+GREP
 CXXCPPFLAGS_FOR_BUILD
 CXXFLAGS_FOR_BUILD
 CXXCPP_FOR_BUILD
@@ -755,7 +756,6 @@ infodir
 docdir
 oldincludedir
 includedir
-runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -842,7 +842,6 @@ datadir='${datarootdir}'
 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 @@ do
   | -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 @@ fi
 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 @@ Fine tuning of the installation directories:
   --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 @@ program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
 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
@@ -6389,121 +6373,1184 @@ do
 _ACEOF
 if ac_fn_cxx_try_cpp "$LINENO"; then :
 
-else
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_build_prog_CXXCPP=$CXXCPP_FOR_BUILD
+
+fi
+  CXXCPP_FOR_BUILD=$ac_cv_build_prog_CXXCPP
+else
+  ac_cv_build_prog_CXXCPP=$CXXCPP_FOR_BUILD
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP_FOR_BUILD" >&5
+$as_echo "$CXXCPP_FOR_BUILD" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C++ preprocessor \"$CXXCPP_FOR_BUILD\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS_FOR_BUILD'
+ac_build_compile='$CC -c $CFLAGS $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5'
+ac_build_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS_FOR_BUILD $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_tool_prefix=$save_ac_tool_prefix
+cross_compiling=$save_cross_compiling
+
+
+
+
+# extract_interface needs to be run on the build system.
+# Since this is the only target that is being built,
+# simply use the build compiler throughout.
+# This ensures that the clang configure checks are
+# performed using the right compiler.
+CXX="$CXX_FOR_BUILD"
+CXXCPP="$CXXCPP_FOR_BUILD"
+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;
+    };
 
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+    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, "");
 
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-  break
-fi
+  }
 
-    done
-    ac_cv_build_prog_CXXCPP=$CXXCPP_FOR_BUILD
+  // 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
+  {
 
-fi
-  CXXCPP_FOR_BUILD=$ac_cv_build_prog_CXXCPP
-else
-  ac_cv_build_prog_CXXCPP=$CXXCPP_FOR_BUILD
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP_FOR_BUILD" >&5
-$as_echo "$CXXCPP_FOR_BUILD" >&6; }
-ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-		     Syntax error
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
+    struct foo {};
 
-else
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+    template<typename T>
+    using member = typename T::member_type;
 
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(0); }
+
+  }
+
+}  // namespace cxx11
+
+#endif  // __cplusplus >= 201103L
 
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
 
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval $cachevar=yes
 else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C++ preprocessor \"$CXXCPP_FOR_BUILD\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
+  eval $cachevar=no
 fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS_FOR_BUILD'
-ac_build_compile='$CC -c $CFLAGS $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5'
-ac_build_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS_FOR_BUILD $LDFLAGS conftest.$ac_ext $LIBS >&5'
+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
 
-ac_tool_prefix=$save_ac_tool_prefix
-cross_compiling=$save_cross_compiling
+$as_echo "#define HAVE_CXX11 1" >>confdefs.h
 
+  fi
 
 
 
-# extract_interface needs to be run on the build system.
-# Since this is the only target that is being built,
-# simply use the build compiler throughout.
-# This ensures that the clang configure checks are
-# performed using the right compiler.
-CXX="$CXX_FOR_BUILD"
-CXXCPP="$CXXCPP_FOR_BUILD"
-EXEEXT="$BUILD_EXEEXT"
-OBJEXT="$BUILD_OBJEXT"
+	fi
+
 
 # Check whether --enable-shared was given.
 if test "${enable_shared+set}" = set; then :
@@ -6544,8 +7591,8 @@ esac
 
 
 
-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 @@ Xsed="$SED -e 1s/^X//"
 
 
 
-{ $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 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   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 @@ esac
 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 @@ for ac_symprfx in "" "_"; do
   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 @@ _LT_EOF
   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 @@ int forced_loaded() { return 2;}
 _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 @@ done
 
 
 
-
 func_stripname_cnf ()
 {
   case $2 in
@@ -10366,8 +11368,8 @@ esac
 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_static=
 	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 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
 
   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 @@ _LT_EOF
 	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 @@ _LT_EOF
       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 @@ _LT_EOF
 	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 @@ fi
 
     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
           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 @@ $as_echo "$lt_cv_irix_exported_symbol" >&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 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       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 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
 	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 @@ cygwin* | mingw* | pw32* | cegcc*)
     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 @@ cygwin* | mingw* | pw32* | cegcc*)
     ;;
 
   *)
-    # 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 @@ fi
   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 @@ striplib=
 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
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+      ;;
+    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
+      fi
+      ;;
+    *)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-    ;;
-  esac
+      ;;
+    esac
+  fi
 fi
 
 
@@ -14780,7 +15773,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
       # 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 @@ fi
 
       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 @@ fi
 	  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 @@ fi
             # 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 @@ fi
 	    # 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 @@ fi
 	      # 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 @@ fi
 	        # 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 @@ fi
 	        # 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 @@ lt_prog_compiler_static_CXX=
 	    ;;
 	esac
 	;;
-      netbsd* | netbsdelf*-gnu)
+      netbsd*)
 	;;
       *qnx* | *nto*)
         # QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -16642,7 +17636,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     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 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
-    cl*)
+    cl* | icl*)
       exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
       ;;
     *)
@@ -16659,9 +17653,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
       ;;
     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 @@ cygwin* | mingw* | pw32* | cegcc*)
     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 @@ cygwin* | mingw* | pw32* | cegcc*)
     ;;
 
   *)
-    # 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 @@ fi
   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 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
 
 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 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 	#include <clang/Lex/PreprocessorOptions.h>
 	#include <clang/Frontend/CompilerInstance.h>
 
+	#include "set_lang_defaults_arg4.h"
+
 int
 main ()
 {
@@ -18445,7 +19426,8 @@ main ()
 	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 @@ want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
 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 @@ want_nocaseglob \
 DLLTOOL \
 sharedlib_from_linklib_cmd \
 AR \
-AR_FLAGS \
 archiver_list_spec \
 STRIP \
 RANLIB \
@@ -20394,7 +21376,9 @@ $as_echo X/"$am_mf" |
     { { $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 @@ sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
 # 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/polly/lib/External/isl/interface/configure.ac b/polly/lib/External/isl/interface/configure.ac
index 9399b0ae05108..357eb60ab76c1 100644
--- a/polly/lib/External/isl/interface/configure.ac
+++ b/polly/lib/External/isl/interface/configure.ac
@@ -17,6 +17,8 @@ CXXCPP="$CXXCPP_FOR_BUILD"
 EXEEXT="$BUILD_EXEEXT"
 OBJEXT="$BUILD_OBJEXT"
 
+AX_CXX_COMPILE_STDCXX_11_NO_OVERRIDE
+
 AC_DISABLE_SHARED
 AC_PROG_LIBTOOL
 

diff  --git a/polly/lib/External/isl/interface/cpp.cc b/polly/lib/External/isl/interface/cpp.cc
index 1295b9c5a20f1..23e2281de1b93 100644
--- a/polly/lib/External/isl/interface/cpp.cc
+++ b/polly/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;
-
-	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);
-}
+	for (const auto &cons : clazz.constructors) {
+		ParmVarDecl *param;
+		QualType type;
+		std::string arg_type;
 
-/* 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;
+		if (!is_implicit_conversion(Method(clazz, cons)))
+			continue;
 
-	osprintf(os, "%*s", indent, " ");
-	va_start(arguments, format);
-	osprintf(os, format, arguments);
-	va_end(arguments);
+		param = cons->getParamDecl(0);
+		type = param->getOriginalType();
+		arg_type = extract_type(type);
+		clazz.construction_types.emplace(arg_type, param);
+	}
 }
 
-/* Convert "l" to a string.
+/* Determine the isl types from which any (proper) class can be constructed
+ * using a unary constructor.
  */
-static std::string to_string(long l)
+void cpp_generator::set_construction_types()
 {
-	std::ostringstream strm;
-	strm << l;
-	return strm.str();
+	for (auto &kvp : classes) {
+		auto &clazz = kvp.second;
+		set_class_construction_types(clazz);
+	}
 }
 
-/* Generate a cpp interface based on the extracted types and functions.
+/* Construct a generator for C++ bindings.
  *
- * Print first a set of forward declarations for all isl wrapper
- * classes, then the declarations of the classes, and at the end all
- * implementations.
+ * The classes and methods are extracted by the constructor
+ * of the generator superclass.
  *
- * 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).
+ * 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::generate()
+cpp_generator::cpp_generator(SourceManager &SM,
+	set<RecordDecl *> &exported_types,
+	set<FunctionDecl *> exported_functions, set<FunctionDecl *> functions) :
+		generator(SM, exported_types, exported_functions, functions)
 {
-	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");
+	set_construction_types();
+	copy_super_methods();
 }
 
-/* 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".
+/* Copy the method called "name" described by "fd" from "super" to "clazz"
+ * with the distance to the original ancestor given by "depth".
+ *
+ * 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_declarations(ostream &os)
+static void copy_method(isl_class &clazz, const isl_class &super,
+	const std::string &name, FunctionDecl *fd, int depth)
 {
-	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);
-	}
+	clazz.methods[name].insert(fd);
+	clazz.copied_from.emplace(fd, super);
+	clazz.copy_depth.emplace(fd, depth);
 }
 
-/* Print all implementations to "os".
+/* Do "fd1" and "fd2" have the same signature (ignoring the first argument
+ * which represents the object class on which the corresponding method
+ * gets called).
  */
-void cpp_generator::print_implementations(ostream &os)
+static bool same_signature(FunctionDecl *fd1, FunctionDecl *fd2)
 {
-	map<string, isl_class>::iterator ci;
-	bool first = true;
+	int n1 = fd1->getNumParams();
+	int n2 = fd2->getNumParams();
 
-	for (ci = classes.begin(); ci != classes.end(); ++ci) {
-		if (first)
-			first = false;
-		else
-			osprintf(os, "\n");
+	if (n1 != n2)
+		return false;
 
-		print_class_impl(os, ci->second);
+	for (int i = 1; i < n1; ++i) {
+		ParmVarDecl *p1 = fd1->getParamDecl(i);
+		ParmVarDecl *p2 = fd2->getParamDecl(i);
+
+		if (p1->getOriginalType() != p2->getOriginalType())
+			return false;
 	}
+
+	return true;
 }
 
-/* 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.
+/* 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_subclass_type(ostream &os, const isl_class &clazz)
+static int copy_depth(const isl_class &clazz, FunctionDecl *fd)
 {
-	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());
+	if (clazz.copy_depth.count(fd) == 0)
+		return 0;
+	return clazz.copy_depth.at(fd);
 }
 
-/* Print declarations for class "clazz" 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"?
  *
- * 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.
+ * 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).
  *
- * 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.
+ * 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(ostream &os, const isl_class &clazz)
+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();
-
-	osprintf(os, "// declarations for isl::%s\n", cppname);
-
-	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 (clazz.methods.count(name) == 0)
+		return false;
+
+	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;
 	}
-	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 false;
 }
 
-/* Print forward declaration of 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".
+ *
+ * Methods that are static in their original class are not copied.
  */
-void cpp_generator::print_class_forward_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)
 {
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
+	for (auto fd : methods) {
+		int depth;
 
-	osprintf(os, "class %s;\n", cppname);
+		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 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);
+/* Add all methods from "super" to "clazz" that have not been overridden
+ * by a method already in "clazz".
  *
- * 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.
+ * Look through all groups of methods with the same name.
  */
-void cpp_generator::print_class_factory_decl(ostream &os,
-	const isl_class &clazz, const std::string &prefix)
+void cpp_generator::copy_super_methods(isl_class &clazz, const isl_class &super)
 {
-	const char *name = clazz.name.c_str();
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-
-	if (clazz.is_type_subclass())
-		return;
+	for (const auto &kvp : super.methods) {
+		const auto &name = kvp.first;
+		const auto &methods = kvp.second;
 
-	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);
+		copy_methods(clazz, name, super, methods);
+	}
 }
 
-/* Print declarations of protected constructors for class "clazz" to "os".
- *
- * Each class has currently one protected constructor:
- *
- * 	1) Constructor from a plain isl_* C pointer
- *
- * Example:
+/* 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".
  *
- * 	set(__isl_take isl_set *ptr);
+ * Make sure the superclasses have copied methods from their superclasses first
+ * since those methods could be copied further down to this class.
  *
- * The raw pointer constructor is kept protected. Object creation is only
- * possible through manage() or manage_copy().
+ * Consider the superclass that appears closest to the subclass first.
  */
-void cpp_generator::print_protected_constructors_decl(ostream &os,
-	const isl_class &clazz)
+void cpp_generator::copy_super_methods(isl_class &clazz, set<string> &done)
 {
-	const char *name = clazz.name.c_str();
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
+	auto supers = find_superclasses(clazz.type);
 
-	osprintf(os, "  inline explicit %s(__isl_take %s *ptr);\n", cppname,
-		 name);
-}
+	for (const auto &super : supers)
+		if (done.count(super) == 0)
+			copy_super_methods(classes[super], done);
+	done.insert(clazz.name);
 
-/* Print declarations of public constructors for class "clazz" to "os".
- *
- * Each class currently has two public constructors:
- *
- * 	1) A default constructor
- * 	2) A copy constructor
- *
- * Example:
- *
- *	set();
- *	set(const set &set);
- */
-void cpp_generator::print_public_constructors_decl(ostream &os,
-	const isl_class &clazz)
-{
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-	osprintf(os, "  inline /* implicit */ %s();\n", cppname);
+	for (const auto &super_name : supers) {
+		const auto &super = classes[super_name];
 
-	osprintf(os, "  inline /* implicit */ %s(const %s &obj);\n",
-		 cppname, cppname);
+		if (super.construction_types.count(clazz.name) == 0)
+			continue;
+		copy_super_methods(clazz, super);
+	}
 }
 
-/* Print declarations for "method" in class "clazz" to "os".
+/* 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.
  *
- * "convert" specifies which of the method arguments should
- * be automatically converted.
+ * 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,
-	const std::vector<bool> &convert)
+void cpp_generator::copy_super_methods()
 {
-	string name = clazz.method_name(method);
+	set<string> done;
 
-	print_named_method_decl(os, clazz, method, name, kind, convert);
-}
+	for (auto &kvp : classes) {
+		auto &clazz = kvp.second;
 
-/* Print declarations for "method" in class "clazz" to "os",
- * without any argument conversions.
- *
- * "kind" specifies the kind of method that should be generated.
- */
-template <>
-void cpp_generator::print_method<cpp_generator::decl>(ostream &os,
-	const isl_class &clazz, FunctionDecl *method, function_kind kind)
-{
-	print_method<decl>(os, clazz,method, kind, {});
+		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);
-}
-
-/* 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);
+	for (const auto &kvp : clazz.methods)
+		print_method_group(kvp.second, kvp.first);
 }
 
-/* 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)
-{
-	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_decl(os, clazz, fd, it->method_name);
-}
-
-/* Print declarations for methods in "clazz" derived from functions
- * that set an enum, to "os".
- */
-void cpp_generator::print_set_enums_decl(ostream &os, const isl_class &clazz)
+void cpp_generator::class_printer::print_set_enums(FunctionDecl *fd)
 {
-	map<FunctionDecl *, vector<set_enum> >::const_iterator it;
+	for (const auto &set : clazz.set_enums.at(fd)) {
+		EnumMethod method(clazz, fd, set.method_name, set.name);
 
-	for (it = clazz.set_enums.begin(); it != clazz.set_enums.end(); ++it)
-		print_set_enums_decl(os, clazz, it->first);
+		print_method(method);
+	}
 }
 
-/* Print a declaration for the "get" method "fd" in class "clazz",
- * using a name that includes the "get_" prefix, to "os".
+/* Print declarations or implementations for methods derived from functions
+ * that set an enum.
  */
-template<>
-void cpp_generator::print_get_method<cpp_generator::decl>(ostream &os,
-	const isl_class &clazz, FunctionDecl *fd)
+void cpp_generator::class_printer::print_set_enums()
 {
-	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 @@ void cpp_generator::print_get_method<cpp_generator::decl>(ostream &os,
  * 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 @@ bool cpp_generator::next_variant(FunctionDecl *fd, std::vector<bool> &convert)
 		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 @@ bool cpp_generator::next_variant(FunctionDecl *fd, std::vector<bool> &convert)
 	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 @@ bool cpp_generator::next_variant(FunctionDecl *fd, std::vector<bool> &convert)
  * whether any of its arguments can be automatically converted
  * from something else, and, if so, generate a method
  * for each combination of converted arguments.
- */
-template <enum cpp_generator::method_part part>
-void cpp_generator::print_method_variants(ostream &os, const isl_class &clazz,
-	FunctionDecl *fd)
-{
-	function_kind kind = get_method_kind(clazz, fd);
-	std::vector<bool> convert(fd->getNumParams());
-
-	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".
+ * Do so by constructing a ConversionMethod that changes the converted arguments
+ * to those of the sources of the conversions.
  *
- * "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.
+ * 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.
  */
-static void print_throw_last_error(ostream &os)
+void cpp_generator::class_printer::print_method_variants(FunctionDecl *fd,
+	const std::string &name)
 {
-	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);
-}
+	Method method(clazz, fd, name);
+	std::vector<bool> convert(method.num_params());
 
-/* 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");
+	if (method.clazz.copied_from.count(method.fd) == 0) {
+		print_method(method);
+		if (clazz.is_get_method(fd))
+			print_get_method(fd);
+	} else {
+		auto super = method.clazz.copied_from.at(method.fd);
+		print_method(ConversionMethod(method, super.name));
 	}
-	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)
+	if (method.kind != Method::Kind::member_method)
 		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");
+	while (next_variant(fd, convert)) {
+		print_method(ConversionMethod(method, [&] (int pos) {
+			return get_param(fd, pos, convert);
+		}));
 	}
-	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.
+/* 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?
  */
-template<>
-void cpp_generator::print_method<cpp_generator::impl>(ostream &os,
-	const isl_class &clazz, FunctionDecl *method, function_kind kind)
+static bool has_single_isl_argument(FunctionDecl *fd)
 {
-	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());
+	ParmVarDecl *param;
 
-	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");
-	} else {
-		print_method_return(os, clazz, method);
-	}
-
-	osprintf(os, "}\n");
-}
+	if (fd->getNumParams() != 2)
+		return false;
 
-/* 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");
+	param = fd->getParamDecl(1);
+	return generator::is_isl_type(param->getOriginalType());
 }
 
-/* Print implementations of constructors for class "clazz" to "os".
+/* 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_constructors_impl(ostream &os,
-	const isl_class &clazz)
+static FunctionDecl *single_local(const isl_class &clazz,
+	const function_set &methods)
 {
-	function_set::const_iterator in;
-	const function_set constructors = clazz.constructors;
+	int count = 0;
+	FunctionDecl *local;
 
-	for (in = constructors.begin(); in != constructors.end(); ++in) {
-		FunctionDecl *cons = *in;
-
-		print_method<impl>(os, clazz, cons, function_kind_constructor);
+	for (const auto &fn : methods) {
+		if (!clazz.first_arg_matches_class(fn))
+			continue;
+		++count;
+		local = fn;
 	}
-}
 
-/* 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");
+	return count == 1 ? local : NULL;
 }
 
-/* Print implementation of destructor for class "clazz" to "os".
- *
- * No explicit destructor is needed for type based subclasses.
+/* 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::print_destructor_impl(ostream &os,
-	const isl_class &clazz)
+void cpp_generator::class_printer::print_descendent_overloads(
+	FunctionDecl *fd, const std::string &name)
 {
-	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::~%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);
+	Method method(clazz, fd, name);
+	ParmVarDecl *param = fd->getParamDecl(1);
+	QualType type = param->getOriginalType();
+	std::string arg = type->getPointeeType().getAsString();
 
-	osprintf(os, "  if (%s_data)\n", callback_name.c_str());
-	print_invalid(os, 4, "cannot release object with persistent callbacks",
-			    "return nullptr");
+	for (const auto &kvp : generator.classes[arg].construction_types) {
+		const auto sub = kvp.second;
+		print_method(ConversionMethod(method, [&] (int pos) {
+			return sub;
+		}));
+	}
 }
 
-/* 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.
+/* Print declarations or definitions for methods called "name"
+ * derived from "methods".
  *
- * If an object has persistent callbacks set, then the underlying
- * C object pointer cannot be released because it references data
- * in the C++ object.
+ * 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::print_ptr_impl(ostream &os, const isl_class &clazz)
+void cpp_generator::class_printer::print_method_group(
+	const function_set &methods, const std::string &name)
 {
-	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;
+	FunctionDecl *local;
 
-	if (clazz.is_type_subclass())
+	for (const auto &fd : methods)
+		print_method_variants(fd, name);
+	if (!want_descendent_overloads(methods))
 		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)
+	local = single_local(clazz, methods);
+	if (!local)
 		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())
+	if (!has_single_isl_argument(local))
 		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);
-	}
-}
-
-/* Print definitions for methods of class "clazz" to "os".
- */
-void cpp_generator::print_methods_impl(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_impl(os, clazz, it->second);
-}
-
-/* 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.
- */
-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_descendent_overloads(local, name);
 }
 
-/* Print definitions for the methods in "clazz" derived from "fd",
- * which sets an enum, to "os".
+/* Print the use of the argument at position "pos" 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".
+ * 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.
  *
- * 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,
-	const function_set &methods)
-{
-	function_set::const_iterator it;
-
-	for (it = methods.begin(); it != methods.end(); ++it)
-		print_method_variants<impl>(os, clazz, *it);
-}
-
-/* Print the use of "param" to "os".
- *
- * "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 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 @@ void cpp_generator::print_method_group_impl(ostream &os, const isl_class &clazz,
  * 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);
-		return;
-	}
-
-	if (is_string(type)) {
-		osprintf(os, "%s.c_str()", name_str);
-		return;
-	}
-
-	if (is_callback(type)) {
-		osprintf(os, "%s_lambda, ", name_str);
-		osprintf(os, "&%s_data", name_str);
-		return;
-	}
-
-	if (!load_from_this_ptr)
-		osprintf(os, "%s.", name_str);
-
-	if (keeps(param)) {
-		osprintf(os, "get()");
-	} else {
-		if (load_from_this_ptr)
-			osprintf(os, "copy()");
-		else
-			osprintf(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.
- */
-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 (type->isIntegerType()) {
+		os << name;
+		return;
+	}
 
-		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);
+	if (generator::is_string(type)) {
+		os << name << ".c_str()";
+		return;
 	}
 
-	check_neg = is_isl_neg_error(return_type);
-	check_null = is_isl_type(return_type);
-	if (!check_null && !check_neg)
+	if (generator::is_callback(type)) {
+		os << name << "_lambda, ";
+		os << "&" << name << "_data";
 		return;
+	}
 
-	if (check_neg)
-		osprintf(os, "  if (res < 0)\n");
-	else
-		osprintf(os, "  if (!res)\n");
-	print_throw_last_error(os);
+	if (!load_from_this_ptr)
+		os << name << ".";
+
+	if (generator::keeps(param)) {
+		os << "get()";
+	} else {
+		if (load_from_this_ptr)
+			os << "copy()";
+		else
+			os << "release()";
+	}
 }
 
-/* Does "fd" modify an object of a subclass based on a type function?
+/* Does the isl function from which this method is derived
+ * 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 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.
+/* Print the header for "method", without newline or semicolon,
+ * using "type_printer" to print argument and return types.
  *
- * "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 @@ ParmVarDecl *cpp_generator::get_param(FunctionDecl *fd, int pos,
  *
  * 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 @@ ParmVarDecl *cpp_generator::get_param(FunctionDecl *fd, int pos,
  * 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 
diff erent 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());
-
-	osprintf(os, "(");
+		os << cppstring;
 
-	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());
-
-		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);
+			os << cpptype << " " << name;
+	});
 
-	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 @@ void cpp_generator::print_method_header(ostream &os, const isl_class &clazz,
  * 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 @@ string cpp_generator::generate_callback_args(QualType type, bool cpp)
 		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 @@ string cpp_generator::generate_callback_args(QualType type, bool cpp)
 	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 @@ string cpp_generator::generate_callback_args(QualType type, bool cpp)
  *
  *      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 
diff erently.
- */
-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 @@ static const char *rename_map[][2] = {
  * 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 @@ string cpp_generator::type2cpp(string type_str)
 }
 
 /* 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.
+ */
+std::string cpp_type_printer::isl_bool() const
+{
+	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_generator::isl_bool2cpp()
+string cpp_type_printer::isl_size() const
 {
-	return checked ? "boolean" : "bool";
+	return "unsigned";
 }
 
 /* Return the namespace of the generated C++ bindings.
+ *
+ * By default, this is "isl::".
+ */
+std::string cpp_type_printer::isl_namespace() const
+{
+	return "isl::";
+}
+
+/* Return the class type given the C++ name.
+ *
+ * By default, directly use the C++ name.
  */
-string cpp_generator::isl_namespace()
+std::string cpp_type_printer::class_type(const std::string &cpp_name) const
 {
-	return checked ? "isl::checked::" : "isl::";
+	return cpp_name;
 }
 
-/* Translate QualType "type" to its C++ name counterpart.
+/* Return the qualified form of the given C++ isl type name appearing
+ * in argument position "arg" (-1 for return type).
  *
- * 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, the argument position is ignored.
+ */
+std::string cpp_type_printer::qualified(int arg, const std::string &cpp_type)
+	const
+{
+	return isl_namespace() + cpp_type;
+}
+
+/* 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));
+}
+
+/* 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.
  */
-string cpp_generator::type2cpp(QualType type)
+std::string cpp_type_printer::param(int arg, QualType type) const
 {
-	if (is_isl_type(type))
-		return isl_namespace() +
-				type2cpp(type->getPointeeType().getAsString());
+	if (cpp_generator::is_isl_type(type))
+		return isl_type(arg, type);
 
-	if (is_isl_bool(type))
-		return isl_bool2cpp();
+	if (cpp_generator::is_isl_bool(type))
+		return isl_bool();
 
-	if (is_isl_stat(type))
-		return checked ? "stat" : "void";
+	if (cpp_generator::is_isl_stat(type))
+		return isl_stat();
 
-	if (is_isl_size(type))
-		return checked ? "class size" : "unsigned";
+	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 @@ bool cpp_generator::is_subclass(QualType subclass_type,
  * 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 @@ bool cpp_generator::is_implicit_conversion(const isl_class &clazz,
  *
  * 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 (generator::is_constructor(method))
+		return Method::Kind::constructor;
+	else if (generator::is_static(clazz, method))
+		return Method::Kind::static_method;
+	else
+		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 
diff erent 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 (is_static(clazz, method))
-		return function_kind_static_method;
+	if (pos == num_params())
+		os << enum_name;
 	else
-		return function_kind_member_method;
+		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/polly/lib/External/isl/interface/cpp.h b/polly/lib/External/isl/interface/cpp.h
index c207af1dd99f0..837cdee3e9394 100644
--- a/polly/lib/External/isl/interface/cpp.h
+++ b/polly/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 
diff erent
+ * 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,
+	};
 
-/* Generator for C++ bindings.
+	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 
diff erent 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.
  *
- * "checked" is set if C++ bindings should be generated
- * that rely on the user to check for error conditions.
+ * "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.
  */
 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/polly/lib/External/isl/interface/depcomp b/polly/lib/External/isl/interface/depcomp
old mode 100644
new mode 100755
index 65cbf7093a1e4..6b391623c4bf0
--- a/polly/lib/External/isl/interface/depcomp
+++ b/polly/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/polly/lib/External/isl/interface/extract_interface.cc b/polly/lib/External/isl/interface/extract_interface.cc
index 26027503751c4..55d4e347c081a 100644
--- a/polly/lib/External/isl/interface/extract_interface.cc
+++ b/polly/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 @@ static void create_main_file_id(SourceManager &SM, const FileEntry *file)
 
 #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 @@ static void generate(MyASTConsumer &consumer, SourceManager &SM)
 		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/polly/lib/External/isl/interface/generator.cc b/polly/lib/External/isl/interface/generator.cc
index dc6ebea797a43..eacbc36a65e6d 100644
--- a/polly/lib/External/isl/interface/generator.cc
+++ b/polly/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 @@ generator::generator(SourceManager &SM, set<RecordDecl *> &exported_types,
 			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 @@ static std::string type_suffix(ParmVarDecl *param)
 /* 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 @@ string isl_class::name_without_type_suffixes(FunctionDecl *method)
 		param = method->getParamDecl(i);
 		type = type_suffix(param);
 
-		name = drop_suffix(name, type);
+		name = generator::drop_suffix(name, type);
 	}
 
 	return name;

diff  --git a/polly/lib/External/isl/interface/generator.h b/polly/lib/External/isl/interface/generator.h
index 6cd0928a4f22a..29faaaac086e5 100644
--- a/polly/lib/External/isl/interface/generator.h
+++ b/polly/lib/External/isl/interface/generator.h
@@ -64,6 +64,18 @@ typedef std::set<FunctionDecl *, function_name_less> function_set;
  * "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 @@ struct isl_class {
 	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 @@ class generator {
 	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/polly/lib/External/isl/interface/install-sh b/polly/lib/External/isl/interface/install-sh
old mode 100644
new mode 100755
index 8175c640fe628..ec298b5374027
--- a/polly/lib/External/isl/interface/install-sh
+++ b/polly/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 @@ posix_mkdir=
 # 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 @@ Options:
      --version  display version info and exit.
 
   -c            (ignored)
-  -C            install only if 
diff erent (preserve the last data modification time)
+  -C            install only if 
diff erent (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 at gnu.org.
+Automake home page: https://www.gnu.org/software/automake/
 "
 
 while test $# -ne 0; do
@@ -137,8 +152,13 @@ while test $# -ne 0; do
     -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 @@ do
     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 @@ do
   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 @@ do
         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-$$
-
-            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-*) 
diff erent_mode=700;;
-                     d????-?--*) 
diff erent_mode=755;;
-                     *) false;;
-                   esac &&
-                   $mkdirprog -m$
diff erent_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;;
+	# 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
+
+	# 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-*) 
diff erent_mode=700;;
+		 d????-?--*) 
diff erent_mode=755;;
+		 *) false;;
+	       esac &&
+	       $mkdirprog -m$
diff erent_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 @@ do
     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 @@ do
           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 @@ do
     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 @@ do
     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 @@ do
         # 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/polly/lib/External/isl/interface/isl.py b/polly/lib/External/isl/interface/isl.py
index 9196cf45b0a68..9e747ed805d7d 100644
--- a/polly/lib/External/isl/interface/isl.py
+++ b/polly/lib/External/isl/interface/isl.py
@@ -101,6 +101,16 @@ def apply(*args):
             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 @@ def as_pw_multi_aff(arg0):
         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 @@ def flat_range_product(arg0, arg1):
         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 @@ def pullback(*args):
             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 @@ def range_product(arg0, arg1):
         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 @@ def union_add(arg0, arg1):
 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 @@ def union_add(arg0, arg1):
 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 @@ def union_add(arg0, arg1):
 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 @@ def add(arg0, arg1):
         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,57 +601,32 @@ def flat_range_product(arg0, arg1):
         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):
+    def gist(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)
+            if not arg1.__class__ is union_set:
+                arg1 = union_set(arg1)
         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)
+        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 get_list(arg0):
-        return arg0.list()
-    def space(arg0):
+    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_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:
-                arg0 = multi_union_pw_aff(arg0)
-        except:
-            raise
-        try:
-            if not arg1.__class__ is union_set:
-                arg1 = union_set(arg1)
-        except:
+        res = isl.isl_multi_union_pw_aff_has_range_tuple_id(arg0.ptr)
+        if res < 0:
             raise
-        ctx = arg0.ctx
-        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
+        return bool(res)
     def intersect_domain(arg0, arg1):
         try:
             if not arg0.__class__ is multi_union_pw_aff:
@@ -643,6 +668,18 @@ def involves_nan(arg0):
         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 @@ def range_product(arg0, arg1):
         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 @@ def set_at(arg0, arg1, arg2):
         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 @@ def size(arg0):
         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 @@ def zero(arg0):
 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 @@ def zero(arg0):
 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 @@ def zero(arg0):
 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 @@ def zero(arg0):
 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 @@ def domain(arg0):
         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 @@ def pullback(*args):
             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 @@ def subtract_domain(*args):
             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 @@ def union_add(arg0, arg1):
 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 @@ def union_add(arg0, arg1):
 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 @@ def add_constant(*args):
             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,57 +1430,32 @@ def flat_range_product(arg0, arg1):
         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):
+    def gist(arg0, arg1):
         try:
             if not arg0.__class__ is multi_pw_aff:
                 arg0 = multi_pw_aff(arg0)
         except:
             raise
+        try:
+            if not arg1.__class__ is set:
+                arg1 = set(arg1)
+        except:
+            return multi_union_pw_aff(arg0).gist(arg1)
         ctx = arg0.ctx
-        res = isl.isl_multi_pw_aff_get_at(arg0.ptr, arg1)
-        obj = pw_aff(ctx=ctx, ptr=res)
+        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 get_at(arg0, arg1):
-        return arg0.at(arg1)
-    def list(arg0):
+    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_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:
-                arg0 = multi_pw_aff(arg0)
-        except:
+        res = isl.isl_multi_pw_aff_has_range_tuple_id(arg0.ptr)
+        if res < 0:
             raise
-        try:
-            if not arg1.__class__ is set:
-                arg1 = set(arg1)
-        except:
-            return multi_union_pw_aff(arg0).gist(arg1)
-        ctx = arg0.ctx
-        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
+        return bool(res)
     def identity(*args):
         if len(args) == 1:
             ctx = args[0].ctx
@@ -1427,6 +1547,29 @@ def involves_param(*args):
                 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 @@ def range_product(arg0, arg1):
         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 @@ def set_at(arg0, arg1, arg2):
         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 @@ def size(arg0):
         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 @@ def zero(arg0):
 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 @@ def zero(arg0):
 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 @@ def zero(arg0):
 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 @@ def zero(arg0):
 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 @@ def zero(arg0):
 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 @@ def add_constant(*args):
             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 @@ def as_multi_aff(arg0):
         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 @@ def cb_func(cb_arg0, cb_arg1, cb_arg2):
             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 @@ def gist(arg0, arg1):
         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 @@ def min_multi_val(arg0):
         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 @@ def range_product(arg0, arg1):
         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 @@ def scale_down(*args):
             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 @@ def subtract_domain(arg0, arg1):
         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 @@ def zero(arg0):
 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 @@ def zero(arg0):
 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 @@ def zero(arg0):
 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 @@ def zero(arg0):
 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 @@ def as_aff(arg0):
         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 @@ def tdiv_r(arg0, arg1):
         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 @@ def union_add(arg0, arg1):
 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 @@ def union_add(arg0, arg1):
 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,17 +3426,49 @@ def add_constant(*args):
             obj = multi_aff(ctx=ctx, ptr=res)
             return obj
         raise Error
-    def bind(arg0, arg1):
+    def as_map(arg0):
         try:
             if not arg0.__class__ is multi_aff:
                 arg0 = multi_aff(arg0)
         except:
             raise
-        try:
-            if not arg1.__class__ is multi_id:
-                arg1 = multi_id(arg1)
-        except:
-            return pw_multi_aff(arg0).bind(arg1)
+        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:
+                arg0 = multi_aff(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is multi_id:
+                arg1 = multi_id(arg1)
+        except:
+            return pw_multi_aff(arg0).bind(arg1)
         ctx = arg0.ctx
         res = isl.isl_multi_aff_bind(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr))
         obj = basic_set(ctx=ctx, ptr=res)
@@ -3099,6 +3503,18 @@ def bind_domain_wrapped_domain(arg0, arg1):
         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,69 +3551,32 @@ def floor(arg0):
         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):
+    def gist(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_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)
+            if not arg1.__class__ is set:
+                arg1 = set(arg1)
         except:
-            raise
+            return pw_multi_aff(arg0).gist(arg1)
         ctx = arg0.ctx
-        res = isl.isl_multi_aff_get_list(arg0.ptr)
-        obj = aff_list(ctx=ctx, ptr=res)
+        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 get_list(arg0):
-        return arg0.list()
-    def space(arg0):
+    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_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:
-                arg0 = multi_aff(arg0)
-        except:
+        res = isl.isl_multi_aff_has_range_tuple_id(arg0.ptr)
+        if res < 0:
             raise
-        try:
-            if not arg1.__class__ is set:
-                arg1 = set(arg1)
-        except:
-            return pw_multi_aff(arg0).gist(arg1)
-        ctx = arg0.ctx
-        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
+        return bool(res)
     def identity(*args):
         if len(args) == 1:
             ctx = args[0].ctx
@@ -3250,6 +3629,26 @@ def involves_nan(arg0):
         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 @@ def range_product(arg0, arg1):
         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 @@ def set_at(arg0, arg1, arg2):
         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 @@ def size(arg0):
         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 @@ def sub(arg0, arg1):
         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 @@ def zero(arg0):
 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 @@ def zero(arg0):
 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 @@ def zero(arg0):
 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 @@ def zero(arg0):
 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 @@ def ceil(arg0):
         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 @@ def ge_set(arg0, arg1):
         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 @@ def sub(arg0, arg1):
         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 @@ def zero_on_domain(*args):
 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 @@ def zero_on_domain(*args):
 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 @@ def zero_on_domain(*args):
 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 @@ def __init__(self, *args, **keywords):
             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 @@ def add(arg0, arg1):
         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,39 +4541,26 @@ def cb_func(cb_arg0, cb_arg1):
             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):
+    def insert(arg0, arg1, arg2):
         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:
-                arg0 = aff_list(arg0)
-        except:
-            raise
-        try:
-            if not arg2.__class__ is aff:
-                arg2 = aff(arg2)
+        except:
+            raise
+        try:
+            if not arg2.__class__ is aff:
+                arg2 = aff(arg2)
         except:
             raise
         ctx = arg0.ctx
@@ -4073,8 +4583,12 @@ def size(arg0):
 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 @@ def size(arg0):
 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 @@ def cb_func(cb_arg0, cb_arg1, cb_arg2):
             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 @@ def access_from(*args):
             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 @@ def access_from(*args):
             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 @@ def call_from(*args):
             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 @@ def call_from(*args):
             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 @@ def expr_from(*args):
             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 @@ def expr_from(*args):
             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 @@ def from_context(arg0):
         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 @@ def node_from(*args):
             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 @@ def node_from_schedule_map(arg0, arg1):
         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 @@ def node_from_schedule_map(arg0, arg1):
 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 @@ def to_C_str(arg0):
         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,29 +6366,29 @@ def init(arg0):
         return obj
     def get_init(arg0):
         return arg0.init()
-    def iterator(arg0):
+    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_get_iterator(arg0.ptr)
-        obj = ast_expr(ctx=ctx, ptr=res)
-        return obj
-    def get_iterator(arg0):
-        return arg0.iterator()
-    def is_degenerate(arg0):
+        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:
                 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)
+        res = isl.isl_ast_node_for_get_iterator(arg0.ptr)
+        obj = ast_expr(ctx=ctx, ptr=res)
+        return obj
+    def get_iterator(arg0):
+        return arg0.iterator()
 
 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 @@ def is_degenerate(arg0):
 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,37 +6460,37 @@ def else_node(arg0):
         return obj
     def get_else_node(arg0):
         return arg0.else_node()
-    def then_node(arg0):
+    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_get_then_node(arg0.ptr)
-        obj = ast_node(ctx=ctx, ptr=res)
-        return obj
-    def get_then_node(arg0):
-        return arg0.then_node()
-    def has_else_node(arg0):
+        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:
                 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)
+        res = isl.isl_ast_node_if_get_then_node(arg0.ptr)
+        obj = ast_node(ctx=ctx, ptr=res)
+        return obj
+    def get_then_node(arg0):
+        return arg0.then_node()
 
 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 @@ def add(arg0, arg1):
         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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def size(arg0):
 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 @@ def size(arg0):
 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 @@ def apply_range(arg0, arg1):
         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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def from_range(arg0):
         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 @@ def lexmin(arg0):
         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 @@ def reverse(arg0):
         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 @@ def zip(arg0):
 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 @@ def zip(arg0):
 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 @@ def zip(arg0):
 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 @@ def zip(arg0):
 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 @@ def apply_range(arg0, arg1):
         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 @@ def domain_product(arg0, arg1):
         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 @@ def cb_func(cb_arg0, cb_arg1):
             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,14 +8290,36 @@ def gist_domain(arg0, arg1):
         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 intersect(arg0, arg1):
+    def has_domain_tuple_id(arg0):
         try:
             if not arg0.__class__ is map:
                 arg0 = map(arg0)
         except:
             raise
-        try:
-            if not arg1.__class__ is map:
+        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:
+                arg0 = map(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is map:
                 arg1 = map(arg1)
         except:
             return union_map(arg0).intersect(arg1)
@@ -8129,6 +8729,18 @@ def range_factor_range(arg0):
         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 @@ def range_reverse(arg0):
         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 @@ def sample(arg0):
         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 @@ def subtract(arg0, arg1):
         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 @@ def zip(arg0):
 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 @@ def zip(arg0):
 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 @@ def zip(arg0):
 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 @@ def zip(arg0):
 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 @@ def apply(arg0, arg1):
         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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def sample_point(arg0):
         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 @@ def subtract(arg0, arg1):
         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 @@ def unwrap(arg0):
 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 @@ def unwrap(arg0):
 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 @@ def unwrap(arg0):
 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 @@ def apply(arg0, arg1):
         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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def params(arg0):
         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 @@ def project_out_param(*args):
             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,31 +10643,88 @@ def sample_point(arg0):
         res = isl.isl_set_sample_point(isl.isl_set_copy(arg0.ptr))
         obj = point(ctx=ctx, ptr=res)
         return obj
-    def subtract(arg0, arg1):
+    def simple_fixed_box_hull(arg0):
         try:
             if not arg0.__class__ is set:
                 arg0 = set(arg0)
         except:
             raise
-        try:
-            if not arg1.__class__ is set:
-                arg1 = set(arg1)
-        except:
-            return union_set(arg0).subtract(arg1)
         ctx = arg0.ctx
-        res = isl.isl_set_subtract(isl.isl_set_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr))
-        obj = set(ctx=ctx, ptr=res)
+        res = isl.isl_set_get_simple_fixed_box_hull(arg0.ptr)
+        obj = fixed_box(ctx=ctx, ptr=res)
         return obj
-    def translation(arg0):
+    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_translation(isl.isl_set_copy(arg0.ptr))
-        obj = map(ctx=ctx, ptr=res)
-        return obj
+        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:
+                arg0 = set(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is set:
+                arg1 = set(arg1)
+        except:
+            return union_set(arg0).subtract(arg1)
+        ctx = arg0.ctx
+        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:
+                arg0 = set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        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 @@ def upper_bound(*args):
 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 @@ def upper_bound(*args):
 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 @@ def upper_bound(*args):
 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 @@ def upper_bound(*args):
 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 @@ def sample_point(arg0):
         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 @@ def union(arg0, arg1):
 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 @@ def __repr__(self):
             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 @@ def space(arg0):
         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 @@ def name(arg0):
         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 @@ def __init__(self, *args, **keywords):
             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 @@ def add(arg0, arg1):
         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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def size(arg0):
 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 @@ def size(arg0):
 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,167 +11594,344 @@ def size(arg0):
 isl.isl_id_list_to_str.restype = POINTER(c_char)
 isl.isl_id_list_to_str.argtypes = [c_void_p]
 
-class multi_id(object):
+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) == 2 and args[0].__class__ is space and args[1].__class__ is id_list:
+        if len(args) == 1 and type(args[0]) == int:
             self.ctx = Context.getDefaultInstance()
-            self.ptr = isl.isl_multi_id_from_id_list(isl.isl_space_copy(args[0].ptr), isl.isl_id_list_copy(args[1].ptr))
+            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_multi_id_read_from_str(self.ctx, args[0].encode('ascii'))
+            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_multi_id_free(self.ptr)
+            isl.isl_map_list_free(self.ptr)
     def __str__(arg0):
         try:
-            if not arg0.__class__ is multi_id:
-                arg0 = multi_id(arg0)
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
         except:
             raise
-        ptr = isl.isl_multi_id_to_str(arg0.ptr)
+        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.multi_id("""%s""")' % s
+            return 'isl.map_list("""%s""")' % s
         else:
-            return 'isl.multi_id("%s")' % s
-    def flat_range_product(arg0, arg1):
+            return 'isl.map_list("%s")' % s
+    def add(arg0, arg1):
         try:
-            if not arg0.__class__ is multi_id:
-                arg0 = multi_id(arg0)
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
         except:
             raise
         try:
-            if not arg1.__class__ is multi_id:
-                arg1 = multi_id(arg1)
+            if not arg1.__class__ is map:
+                arg1 = map(arg1)
         except:
             raise
         ctx = arg0.ctx
-        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)
+        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 multi_id:
-                arg0 = multi_id(arg0)
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
         except:
             raise
         ctx = arg0.ctx
-        res = isl.isl_multi_id_get_at(arg0.ptr, arg1)
-        obj = id(ctx=ctx, ptr=res)
+        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 list(arg0):
-        try:
-            if not arg0.__class__ is multi_id:
-                arg0 = multi_id(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_id_get_list(arg0.ptr)
-        obj = id_list(ctx=ctx, ptr=res)
-        return obj
-    def get_list(arg0):
-        return arg0.list()
-    def space(arg0):
+    def clear(arg0):
         try:
-            if not arg0.__class__ is multi_id:
-                arg0 = multi_id(arg0)
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
         except:
             raise
         ctx = arg0.ctx
-        res = isl.isl_multi_id_get_space(arg0.ptr)
-        obj = space(ctx=ctx, ptr=res)
+        res = isl.isl_map_list_clear(isl.isl_map_list_copy(arg0.ptr))
+        obj = map_list(ctx=ctx, ptr=res)
         return obj
-    def get_space(arg0):
-        return arg0.space()
-    def plain_is_equal(arg0, arg1):
+    def concat(arg0, arg1):
         try:
-            if not arg0.__class__ is multi_id:
-                arg0 = multi_id(arg0)
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
         except:
             raise
         try:
-            if not arg1.__class__ is multi_id:
-                arg1 = multi_id(arg1)
+            if not arg1.__class__ is map_list:
+                arg1 = map_list(arg1)
         except:
             raise
         ctx = arg0.ctx
-        res = isl.isl_multi_id_plain_is_equal(arg0.ptr, arg1.ptr)
-        if res < 0:
-            raise
-        return bool(res)
-    def range_product(arg0, arg1):
+        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 multi_id:
-                arg0 = multi_id(arg0)
+            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 arg1.__class__ is multi_id:
-                arg1 = multi_id(arg1)
+            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_multi_id_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 set_at(arg0, arg1, arg2):
+        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 multi_id:
-                arg0 = multi_id(arg0)
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
         except:
             raise
         try:
-            if not arg2.__class__ is id:
-                arg2 = id(arg2)
+            if not arg2.__class__ is map:
+                arg2 = map(arg2)
         except:
             raise
         ctx = arg0.ctx
-        res = isl.isl_multi_id_set_at(isl.isl_multi_id_copy(arg0.ptr), arg1, isl.isl_id_copy(arg2.ptr))
-        obj = multi_id(ctx=ctx, ptr=res)
+        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 multi_id:
-                arg0 = multi_id(arg0)
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
         except:
             raise
         ctx = arg0.ctx
-        res = isl.isl_multi_id_size(arg0.ptr)
+        res = isl.isl_map_list_size(arg0.ptr)
         if res < 0:
             raise
         return int(res)
 
-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_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_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:
+            self.ctx = keywords["ctx"]
+            self.ptr = keywords["ptr"]
+            return
+        if len(args) == 2 and args[0].__class__ is space and args[1].__class__ is id_list:
+            self.ctx = Context.getDefaultInstance()
+            self.ptr = isl.isl_multi_id_from_id_list(isl.isl_space_copy(args[0].ptr), isl.isl_id_list_copy(args[1].ptr))
+            return
+        if len(args) == 1 and type(args[0]) == str:
+            self.ctx = Context.getDefaultInstance()
+            self.ptr = isl.isl_multi_id_read_from_str(self.ctx, args[0].encode('ascii'))
+            return
+        raise Error
+    def __del__(self):
+        if hasattr(self, 'ptr'):
+            isl.isl_multi_id_free(self.ptr)
+    def __str__(arg0):
+        try:
+            if not arg0.__class__ is multi_id:
+                arg0 = multi_id(arg0)
+        except:
+            raise
+        ptr = isl.isl_multi_id_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.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:
+                arg0 = multi_id(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is multi_id:
+                arg1 = multi_id(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        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 list(arg0):
+        try:
+            if not arg0.__class__ is multi_id:
+                arg0 = multi_id(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_id_get_list(arg0.ptr)
+        obj = id_list(ctx=ctx, ptr=res)
+        return obj
+    def get_list(arg0):
+        return arg0.list()
+    def plain_is_equal(arg0, arg1):
+        try:
+            if not arg0.__class__ is multi_id:
+                arg0 = multi_id(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is multi_id:
+                arg1 = multi_id(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_id_plain_is_equal(arg0.ptr, arg1.ptr)
+        if res < 0:
+            raise
+        return bool(res)
+    def range_product(arg0, arg1):
+        try:
+            if not arg0.__class__ is multi_id:
+                arg0 = multi_id(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is multi_id:
+                arg1 = multi_id(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_id_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 set_at(arg0, arg1, arg2):
+        try:
+            if not arg0.__class__ is multi_id:
+                arg0 = multi_id(arg0)
+        except:
+            raise
+        try:
+            if not arg2.__class__ is id:
+                arg2 = id(arg2)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_id_set_at(isl.isl_multi_id_copy(arg0.ptr), arg1, isl.isl_id_copy(arg2.ptr))
+        obj = multi_id(ctx=ctx, ptr=res)
+        return obj
+    def size(arg0):
+        try:
+            if not arg0.__class__ is multi_id:
+                arg0 = multi_id(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_id_size(arg0.ptr)
+        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_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_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,21 +11991,6 @@ def add(*args):
             obj = multi_val(ctx=ctx, ptr=res)
             return obj
         raise Error
-    def flat_range_product(arg0, arg1):
-        try:
-            if not arg0.__class__ is multi_val:
-                arg0 = multi_val(arg0)
-        except:
-            raise
-        try:
-            if not arg1.__class__ is multi_val:
-                arg1 = multi_val(arg1)
-        except:
-            raise
-        ctx = arg0.ctx
-        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):
         try:
             if not arg0.__class__ is multi_val:
@@ -11023,30 +12003,32 @@ def at(arg0, arg1):
         return obj
     def get_at(arg0, arg1):
         return arg0.at(arg1)
-    def list(arg0):
+    def flat_range_product(arg0, arg1):
         try:
             if not arg0.__class__ is multi_val:
                 arg0 = multi_val(arg0)
         except:
             raise
+        try:
+            if not arg1.__class__ is multi_val:
+                arg1 = multi_val(arg1)
+        except:
+            raise
         ctx = arg0.ctx
-        res = isl.isl_multi_val_get_list(arg0.ptr)
-        obj = val_list(ctx=ctx, ptr=res)
+        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 get_list(arg0):
-        return arg0.list()
-    def space(arg0):
+    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_space(arg0.ptr)
-        obj = space(ctx=ctx, ptr=res)
-        return obj
-    def get_space(arg0):
-        return arg0.space()
+        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:
@@ -11058,6 +12040,18 @@ def involves_nan(arg0):
         if res < 0:
             raise
         return bool(res)
+    def list(arg0):
+        try:
+            if not arg0.__class__ is multi_val:
+                arg0 = multi_val(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_val_get_list(arg0.ptr)
+        obj = val_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_val:
@@ -11144,6 +12138,28 @@ def range_product(arg0, arg1):
         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 @@ def set_at(arg0, arg1, arg2):
         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 @@ def size(arg0):
         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 @@ def zero(arg0):
 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 @@ def zero(arg0):
 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,8 +12315,12 @@ def zero(arg0):
 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_sub.restype = 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
 isl.isl_multi_val_zero.argtypes = [c_void_p]
@@ -11321,9 +12369,21 @@ def multi_val(arg0):
         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 @@ def __init__(self, *args, **keywords):
             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 @@ def add(arg0, arg1):
         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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def size(arg0):
 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 @@ def size(arg0):
 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 @@ def __init__(self, *args, **keywords):
             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 @@ def add(arg0, arg1):
         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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def size(arg0):
 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 @@ def size(arg0):
 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 @@ def __repr__(self):
             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 @@ def domain(arg0):
         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 @@ def map(arg0):
         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 @@ def root(arg0):
         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,28 +12879,28 @@ def __repr__(self):
             return 'isl.schedule_constraints("""%s""")' % s
         else:
             return 'isl.schedule_constraints("%s")' % s
-    def compute_schedule(arg0):
+    def coincidence(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)
+        res = isl.isl_schedule_constraints_get_coincidence(arg0.ptr)
+        obj = union_map(ctx=ctx, ptr=res)
         return obj
-    def coincidence(arg0):
+    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_get_coincidence(arg0.ptr)
-        obj = union_map(ctx=ctx, ptr=res)
+        res = isl.isl_schedule_constraints_compute_schedule(isl.isl_schedule_constraints_copy(arg0.ptr))
+        obj = schedule(ctx=ctx, ptr=res)
         return obj
-    def get_coincidence(arg0):
-        return arg0.coincidence()
     def conditional_validity(arg0):
         try:
             if not arg0.__class__ is schedule_constraints:
@@ -11879,41 +12949,29 @@ def domain(arg0):
         return obj
     def get_domain(arg0):
         return arg0.domain()
-    def proximity(arg0):
+    @staticmethod
+    def on_domain(arg0):
         try:
-            if not arg0.__class__ is schedule_constraints:
-                arg0 = schedule_constraints(arg0)
+            if not arg0.__class__ is union_set:
+                arg0 = union_set(arg0)
         except:
             raise
         ctx = arg0.ctx
-        res = isl.isl_schedule_constraints_get_proximity(arg0.ptr)
-        obj = union_map(ctx=ctx, ptr=res)
+        res = isl.isl_schedule_constraints_on_domain(isl.isl_union_set_copy(arg0.ptr))
+        obj = schedule_constraints(ctx=ctx, ptr=res)
         return obj
-    def get_proximity(arg0):
-        return arg0.proximity()
-    def validity(arg0):
+    def proximity(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)
+        res = isl.isl_schedule_constraints_get_proximity(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 get_proximity(arg0):
+        return arg0.proximity()
     def set_coincidence(arg0, arg1):
         try:
             if not arg0.__class__ is schedule_constraints:
@@ -11994,13 +13052,25 @@ def set_validity(arg0, arg1):
         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 @@ def set_validity(arg0, arg1):
 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 @@ def set_validity(arg0, arg1):
 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 @@ def ancestor(arg0, arg1):
         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 @@ def child(arg0, arg1):
         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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def cb_func(cb_arg0, cb_arg1):
             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,7 +13352,7 @@ def from_extension(arg0):
         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):
+    def graft_after(arg0, arg1):
         try:
             if not arg0.__class__ is schedule_node:
                 arg0 = schedule_node(arg0)
@@ -12266,134 +13364,25 @@ def ancestor_child_position(arg0, 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):
+        res = isl.isl_schedule_node_graft_after(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_schedule_node_copy(arg1.ptr))
+        obj = schedule_node(ctx=ctx, ptr=res)
+        return obj
+    def graft_before(arg0, arg1):
         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:
+        try:
+            if not arg1.__class__ is schedule_node:
+                arg1 = schedule_node(arg1)
+        except:
             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:
-                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_graft_after(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_schedule_node_copy(arg1.ptr))
-        obj = schedule_node(ctx=ctx, ptr=res)
-        return obj
-    def graft_before(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_graft_before(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_schedule_node_copy(arg1.ptr))
-        obj = schedule_node(ctx=ctx, ptr=res)
-        return obj
-    def has_children(arg0):
+        ctx = arg0.ctx
+        res = isl.isl_schedule_node_graft_before(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_schedule_node_copy(arg1.ptr))
+        obj = schedule_node(ctx=ctx, ptr=res)
+        return obj
+    def has_children(arg0):
         try:
             if not arg0.__class__ is schedule_node:
                 arg0 = schedule_node(arg0)
@@ -12581,16 +13570,15 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def parent(arg0):
         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 @@ def root(arg0):
         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 @@ def root(arg0):
 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 @@ def root(arg0):
 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 @@ def ast_isolate_option(arg0):
         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,32 +13913,57 @@ def n_member(arg0):
         if res < 0:
             raise
         return int(res)
-    def scale(arg0, arg1):
+    def partial_schedule(arg0):
         try:
             if not arg0.__class__ is schedule_node:
                 arg0 = schedule_node(arg0)
         except:
             raise
-        try:
-            if not arg1.__class__ is multi_val:
-                arg1 = multi_val(arg1)
-        except:
-            raise
         ctx = arg0.ctx
-        res = isl.isl_schedule_node_band_scale(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr))
-        obj = schedule_node(ctx=ctx, ptr=res)
+        res = isl.isl_schedule_node_band_get_partial_schedule(arg0.ptr)
+        obj = multi_union_pw_aff(ctx=ctx, ptr=res)
         return obj
-    def scale_down(arg0, arg1):
+    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
-        try:
-            if not arg1.__class__ is multi_val:
-                arg1 = multi_val(arg1)
-        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:
+                arg0 = schedule_node(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is multi_val:
+                arg1 = multi_val(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_node_band_scale(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr))
+        obj = schedule_node(ctx=ctx, ptr=res)
+        return obj
+    def scale_down(arg0, arg1):
+        try:
+            if not arg0.__class__ is schedule_node:
+                arg0 = schedule_node(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is multi_val:
+                arg1 = multi_val(arg1)
+        except:
+            raise
         ctx = arg0.ctx
         res = isl.isl_schedule_node_band_scale_down(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr))
         obj = schedule_node(ctx=ctx, ptr=res)
@@ -13012,15 +14078,15 @@ def member_set_ast_loop_separate(arg0, arg1):
 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 @@ def add_named_tuple(*args):
             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 @@ def domain(arg0):
         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:
@@ -13575,182 +14686,511 @@ def flatten_domain(arg0):
         except:
             raise
         ctx = arg0.ctx
-        res = isl.isl_space_flatten_domain(isl.isl_space_copy(arg0.ptr))
+        res = isl.isl_space_flatten_domain(isl.isl_space_copy(arg0.ptr))
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def flatten_range(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        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:
+                arg0 = space(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is space:
+                arg1 = space(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_is_equal(arg0.ptr, arg1.ptr)
+        if res < 0:
+            raise
+        return bool(res)
+    def is_wrapping(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_is_wrapping(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
+    def map_from_set(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        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:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_params(isl.isl_space_copy(arg0.ptr))
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def product(arg0, arg1):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is space:
+                arg1 = space(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_product(isl.isl_space_copy(arg0.ptr), isl.isl_space_copy(arg1.ptr))
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def range(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        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:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_range_reverse(isl.isl_space_copy(arg0.ptr))
         obj = space(ctx=ctx, ptr=res)
         return obj
-    def flatten_range(arg0):
+    def range_tuple_id(arg0):
         try:
             if not arg0.__class__ is space:
                 arg0 = space(arg0)
         except:
             raise
         ctx = arg0.ctx
-        res = isl.isl_space_flatten_range(isl.isl_space_copy(arg0.ptr))
-        obj = space(ctx=ctx, ptr=res)
+        res = isl.isl_space_get_range_tuple_id(arg0.ptr)
+        obj = id(ctx=ctx, ptr=res)
         return obj
-    def is_equal(arg0, arg1):
+    def get_range_tuple_id(arg0):
+        return arg0.range_tuple_id()
+    def reverse(arg0):
         try:
             if not arg0.__class__ is space:
                 arg0 = space(arg0)
         except:
             raise
-        try:
-            if not arg1.__class__ is space:
-                arg1 = space(arg1)
-        except:
-            raise
         ctx = arg0.ctx
-        res = isl.isl_space_is_equal(arg0.ptr, arg1.ptr)
-        if res < 0:
-            raise
-        return bool(res)
-    def is_wrapping(arg0):
+        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:
                 arg0 = space(arg0)
         except:
             raise
         ctx = arg0.ctx
-        res = isl.isl_space_is_wrapping(arg0.ptr)
-        if res < 0:
-            raise
-        return bool(res)
-    def map_from_set(arg0):
+        res = isl.isl_space_uncurry(isl.isl_space_copy(arg0.ptr))
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    @staticmethod
+    def unit():
+        ctx = Context.getDefaultInstance()
+        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_map_from_set(isl.isl_space_copy(arg0.ptr))
-        obj = space(ctx=ctx, ptr=res)
+        res = isl.isl_space_universe_map(isl.isl_space_copy(arg0.ptr))
+        obj = map(ctx=ctx, ptr=res)
         return obj
-    def params(arg0):
+    def universe_set(arg0):
         try:
             if not arg0.__class__ is space:
                 arg0 = space(arg0)
         except:
             raise
         ctx = arg0.ctx
-        res = isl.isl_space_params(isl.isl_space_copy(arg0.ptr))
-        obj = space(ctx=ctx, ptr=res)
+        res = isl.isl_space_universe_set(isl.isl_space_copy(arg0.ptr))
+        obj = set(ctx=ctx, ptr=res)
         return obj
-    def product(arg0, arg1):
+    def unwrap(arg0):
         try:
             if not arg0.__class__ is space:
                 arg0 = space(arg0)
         except:
             raise
-        try:
-            if not arg1.__class__ is space:
-                arg1 = space(arg1)
-        except:
-            raise
         ctx = arg0.ctx
-        res = isl.isl_space_product(isl.isl_space_copy(arg0.ptr), isl.isl_space_copy(arg1.ptr))
+        res = isl.isl_space_unwrap(isl.isl_space_copy(arg0.ptr))
         obj = space(ctx=ctx, ptr=res)
         return obj
-    def range(arg0):
+    def wrap(arg0):
         try:
             if not arg0.__class__ is space:
                 arg0 = space(arg0)
         except:
             raise
         ctx = arg0.ctx
-        res = isl.isl_space_range(isl.isl_space_copy(arg0.ptr))
+        res = isl.isl_space_wrap(isl.isl_space_copy(arg0.ptr))
         obj = space(ctx=ctx, ptr=res)
         return obj
-    def range_reverse(arg0):
+    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_range_reverse(isl.isl_space_copy(arg0.ptr))
-        obj = space(ctx=ctx, ptr=res)
+        res = isl.isl_space_zero_aff_on_domain(isl.isl_space_copy(arg0.ptr))
+        obj = aff(ctx=ctx, ptr=res)
         return obj
-    def reverse(arg0):
+    def zero_multi_aff(arg0):
         try:
             if not arg0.__class__ is space:
                 arg0 = space(arg0)
         except:
             raise
         ctx = arg0.ctx
-        res = isl.isl_space_reverse(isl.isl_space_copy(arg0.ptr))
-        obj = space(ctx=ctx, ptr=res)
+        res = isl.isl_space_zero_multi_aff(isl.isl_space_copy(arg0.ptr))
+        obj = multi_aff(ctx=ctx, ptr=res)
         return obj
-    def uncurry(arg0):
+    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_uncurry(isl.isl_space_copy(arg0.ptr))
-        obj = space(ctx=ctx, ptr=res)
-        return obj
-    @staticmethod
-    def unit():
-        ctx = Context.getDefaultInstance()
-        res = isl.isl_space_unit(ctx)
-        obj = space(ctx=ctx, ptr=res)
+        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 unwrap(arg0):
+    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_unwrap(isl.isl_space_copy(arg0.ptr))
-        obj = space(ctx=ctx, ptr=res)
+        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 wrap(arg0):
+    def zero_multi_val(arg0):
         try:
             if not arg0.__class__ is space:
                 arg0 = space(arg0)
         except:
             raise
         ctx = arg0.ctx
-        res = isl.isl_space_wrap(isl.isl_space_copy(arg0.ptr))
-        obj = space(ctx=ctx, ptr=res)
+        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 @@ def __init__(self, *args, **keywords):
             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 @@ def add(arg0, arg1):
         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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def size(arg0):
 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 @@ def size(arg0):
 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 @@ def __init__(self, *args, **keywords):
             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 @@ def add(arg0, arg1):
         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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def size(arg0):
 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 @@ def size(arg0):
 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 @@ def cmp_si(arg0, arg1):
         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 @@ def ge(arg0, arg1):
         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 @@ def negone():
         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 @@ def sub(arg0, arg1):
         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 @@ def zero():
 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 @@ def zero():
 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 @@ def zero():
 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 @@ def zero():
 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 @@ def __init__(self, *args, **keywords):
             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 @@ def add(arg0, arg1):
         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 @@ def cb_func(cb_arg0, cb_arg1):
             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 @@ def size(arg0):
 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 @@ def size(arg0):
 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/polly/lib/External/isl/interface/isl_config.h.in b/polly/lib/External/isl/interface/isl_config.h.in
index 4bf1b296d8bb8..e116521d69b56 100644
--- a/polly/lib/External/isl/interface/isl_config.h.in
+++ b/polly/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/polly/lib/External/isl/interface/ltmain.sh b/polly/lib/External/isl/interface/ltmain.sh
index 0cb7f90d3bd7a..48cea9b0e5bd4 100644
--- a/polly/lib/External/isl/interface/ltmain.sh
+++ b/polly/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 at 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 @@ package_revision=2.4.6
 # 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 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/>.
+# 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.
 
-# Please report bugs or propose patches to gary at gnu.org.
+# Please report bugs or propose patches to:
+# <https://github.com/gnulib-modules/bootstrap/issues>
 
 
 ## ------ ##
@@ -140,9 +131,6 @@ do
 	fi"
 done
 
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
 # Make sure IFS has a sensible default
 sp=' '
 nl='
@@ -159,6 +147,26 @@ if test "${PATH_SEPARATOR+set}" != set; then
 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 @@ test -z "$SED" && {
     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 @@ test -z "$GREP" && {
     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 @@ EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
 # 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 @@ if test yes = "$_G_HAVE_PLUSEQ_OP"; then
   {
     $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_relative_path ()
 }
 
 
-# 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
-        *[\\\`\"\$]*)
-	  _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"
+    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
 
-      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\"
+      # Quote for eval.
+      case $func_quote_portable_result in
+        *[\\\`\"\$]*)
+          case $func_quote_portable_result in
+            *[\[\*\?]*)
+              func_quote_portable_result=`$ECHO "$func_quote_portable_result" \
+                  | $SED "$sed_quote_subst"`
+              break
+              ;;
+          esac
+
+          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 ()
-{
-    $debug_cmd
+# 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
 
-    case $1 in
-      *[\\\`\"]*)
-	_G_arg=`$ECHO "$1" | $SED \
-	    -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
-      *)
-        _G_arg=$1 ;;
+
+# 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 ()
+{
+    _G_quote_expand=false
+    case ,$1, in
+      *,expand,*)
+        _G_quote_expand=:
+        ;;
     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\"
+    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_for_expand_result=$_G_arg
+
+# 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 @@ func_show_eval ()
     _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 @@ func_show_eval_locale ()
     _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 @@ func_lt_ver ()
 # 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 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.
-
-# 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.
+# 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.
 
-# 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:
+# <https://github.com/gnulib-modules/bootstrap/issues>
 
-# Please report bugs or propose patches to gary at gnu.org.
+# Set a version string for this script.
+scriptversion=2018-07-24.06; # UTC
 
 
 ## ------ ##
@@ -1415,7 +1533,7 @@ scriptversion=2015-10-07.11; # UTC
 #
 # 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 @@ scriptversion=2015-10-07.11; # UTC
 # 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 @@ fatal_help="Try '\$progname --help' for more information."
 ## ------------------------- ##
 
 # 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_add_hook ()
 
 # 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_remove_hook ()
 }
 
 
+# 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 @@ func_run_hooks ()
 {
     $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 @@ func_run_hooks ()
 ## --------------- ##
 
 # 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 @@ func_run_hooks ()
 #        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 @@ func_run_hooks ()
 #
 #        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 @@ func_run_hooks ()
 #                         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 @@ func_run_hooks ()
 #
 #        $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 @@ func_options_finish ()
 {
     $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 @@ func_options ()
 {
     $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 @@ func_options ()
 # 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 @@ func_options_prep ()
     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 @@ func_parse_options ()
 {
     $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 @@ func_parse_options ()
 
         --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 @@ func_parse_options ()
                       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 @@ func_parse_options ()
                       ;;
       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 @@ func_validate_options ()
 {
     $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_missing_arg ()
 
 # 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 @@ then
 
       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_usage_message ()
 # 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
-        }
-        :go
-        /^# Written by /,/# warranty; / {
-          s|^# ||
-          s|^# *$||
-          s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
-          p
+        /^# Written by /!b
+        s|^# ||; p; n
+
+        :fwd2blnk
+        /./ {
+          n
+          b fwd2blnk
         }
-        /^# Written by / {
-          s|^# ||
-          p
+        p; n
+
+        :holdwrnt
+        s|^# ||
+        s|^# *$||
+        /^Copyright /!{
+          /./H
+          n
+          b holdwrnt
         }
-        /^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 @@ func_version ()
 # 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 @@ include the following information:
        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 @@ fi
 # 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 @@ libtool_options_prep ()
 
     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 @@ libtool_parse_options ()
 
     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 @@ libtool_validate_options ()
     }
 
     # 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 @@ func_mode_compile ()
       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 @@ compiler."
 
     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 @@ func_mode_install ()
        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 @@ func_mode_install ()
 
     # 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 @@ func_mode_install ()
       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 @@ func_mode_install ()
 
     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 @@ func_mode_install ()
 	        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 @@ else
   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 @@ func_fallback_echo ()
 \$1
 _LTECHO_EOF'
 }
-    ECHO=\"$qECHO\"
+    ECHO=$qECHO
   fi
 
 # Very basic option parsing. These options are (a) specific to
@@ -6703,9 +6826,9 @@ func_mode_link ()
     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 @@ func_mode_link ()
 	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 @@ func_mode_link ()
 	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 @@ func_mode_link ()
 
       # -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 @@ func_mode_link ()
       # -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 @@ func_mode_link ()
 	  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 @@ func_mode_link ()
       *)
 	# 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 @@ func_mode_link ()
 	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 @@ func_mode_link ()
 	    # 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 @@ func_mode_link ()
 	    revision=$number_minor
 	    lt_irix_increment=no
 	    ;;
-	  *)
-	    func_fatal_configuration "$modename: unknown library version type '$version_type'"
-	    ;;
 	  esac
 	  ;;
 	no)
@@ -10037,8 +10152,8 @@ EOF
 	    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 @@ EOF
 	  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 @@ EOF
 	  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 @@ EOF
 	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/polly/lib/External/isl/interface/missing b/polly/lib/External/isl/interface/missing
old mode 100644
new mode 100755
index 625aeb11897a2..8d0eaad250fc1
--- a/polly/lib/External/isl/interface/missing
+++ b/polly/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 at iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify

diff  --git a/polly/lib/External/isl/interface/plain_cpp.cc b/polly/lib/External/isl/interface/plain_cpp.cc
new file mode 100644
index 0000000000000..ae15c34dbe4a9
--- /dev/null
+++ b/polly/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 
diff erently.
+ */
+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/polly/lib/External/isl/interface/plain_cpp.h b/polly/lib/External/isl/interface/plain_cpp.h
new file mode 100644
index 0000000000000..264480212dd3b
--- /dev/null
+++ b/polly/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/polly/lib/External/isl/interface/python.cc b/polly/lib/External/isl/interface/python.cc
index fe8cd0ce6aed3..686bcc71b91c9 100644
--- a/polly/lib/External/isl/interface/python.cc
+++ b/polly/lib/External/isl/interface/python.cc
@@ -257,9 +257,8 @@ void python_generator::print_callback(ParmVarDecl *param, int arg)
 		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 @@ void python_generator::print_arg_in_call(FunctionDecl *fd, const char *fmt,
  */
 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/polly/lib/External/isl/interface/set_lang_defaults_arg4.h b/polly/lib/External/isl/interface/set_lang_defaults_arg4.h
new file mode 100644
index 0000000000000..82af7ff655b69
--- /dev/null
+++ b/polly/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/polly/lib/External/isl/interface/template_cpp.cc b/polly/lib/External/isl/interface/template_cpp.cc
new file mode 100644
index 0000000000000..bf138032b7ae2
--- /dev/null
+++ b/polly/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 
diff erent 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 
diff erent, 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 
diff erent 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/polly/lib/External/isl/interface/template_cpp.h b/polly/lib/External/isl/interface/template_cpp.h
new file mode 100644
index 0000000000000..a141a4826caa4
--- /dev/null
+++ b/polly/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/polly/lib/External/isl/isl_aff.c b/polly/lib/External/isl/isl_aff.c
index b840a52c2cbe7..40ca78dec6b29 100644
--- a/polly/lib/External/isl/isl_aff.c
+++ b/polly/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 @@ __isl_give isl_aff *isl_aff_zero_on_domain_space(__isl_take isl_space *space)
 	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 @@ __isl_give isl_aff *isl_aff_param_on_domain_space_id(
 	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 @@ __isl_give isl_multi_aff *isl_multi_aff_domain_map(__isl_take isl_space *space)
 	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 @@ __isl_give isl_multi_aff *isl_multi_aff_range_map(__isl_take isl_space *space)
 	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 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_domain_map(
 	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 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map(
 	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 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out_map(
 	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 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity_on_domain_space(
 	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 @@ __isl_give isl_set *isl_multi_aff_lex_gt_set(__isl_take isl_multi_aff *ma1,
 #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 @@ static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_div(
  *
  *	-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 @@ static int is_potential_div_constraint(isl_int *c, int offset, int d, int total)
  *
  *	-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 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map)
 	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 @@ __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_map(
 	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 @@ __isl_give isl_multi_aff *isl_multi_aff_substitute(
 	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 @@ __isl_give isl_multi_aff *isl_multi_aff_substitute(
  * 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_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
 					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 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
 
 			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 @@ static
 
 /* 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 @@ __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
 	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 @@ isl_stat isl_pw_aff_check_match_domain_space(__isl_keep isl_pw_aff *pa,
 #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 @@ __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_multi_aff(
 	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 @@ __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff(
 	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 @@ __isl_give isl_pw_aff *isl_pw_aff_param_on_domain_id(
 /* 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 @@ __isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space(
 	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 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_multi_val_on_domain(
 	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 @@ __isl_give isl_union_pw_aff *isl_union_pw_aff_pullback_union_pw_multi_aff(
 #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 @@ __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_aff(
 	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 @@ isl_multi_union_pw_aff_from_union_pw_multi_aff(
 	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 @@ __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map(
 	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/polly/lib/External/isl/isl_aff_map.c b/polly/lib/External/isl/isl_aff_map.c
index 29366f5c5d778..f661b824d2ef0 100644
--- a/polly/lib/External/isl/isl_aff_map.c
+++ b/polly/lib/External/isl/isl_aff_map.c
@@ -228,6 +228,14 @@ __isl_give isl_map *isl_map_from_multi_aff(__isl_take isl_multi_aff *ma)
 	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 @@ __isl_give isl_set *isl_set_from_multi_aff(__isl_take isl_multi_aff *ma)
 	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 @@ __isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
 	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 @@ __isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
 	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 @@ __isl_give isl_set *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
 	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 @@ __isl_give isl_map *isl_map_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa)
 	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 @@ __isl_give isl_set *isl_set_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa)
 	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_give isl_union_map *isl_union_map_from_union_pw_multi_aff(
 	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/polly/lib/External/isl/isl_aff_private.h b/polly/lib/External/isl/isl_aff_private.h
index 8c94f048c28ad..473add3b3ab62 100644
--- a/polly/lib/External/isl/isl_aff_private.h
+++ b/polly/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_normalize(__isl_take isl_aff *aff);
 __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(__isl_take isl_pw_aff *pwaff,
 __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_stat isl_seq_preimage(isl_int *dst, isl_int *src,
 __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/polly/lib/External/isl/isl_ast_build.c b/polly/lib/External/isl/isl_ast_build.c
index c62f47c702037..a0776e8235062 100644
--- a/polly/lib/External/isl/isl_ast_build.c
+++ b/polly/lib/External/isl/isl_ast_build.c
@@ -648,9 +648,9 @@ __isl_give isl_map *isl_ast_build_get_schedule_map(
 /* 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_give isl_multi_aff *isl_ast_build_get_stride_expansion(
 {
 	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_include_stride(
 __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 @@ isl_bool isl_ast_build_has_stride(__isl_keep isl_ast_build *build, int pos)
  *
  *	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/polly/lib/External/isl/isl_ast_build_private.h b/polly/lib/External/isl/isl_ast_build_private.h
index 9767679fe3b9b..1128e632c3ac8 100644
--- a/polly/lib/External/isl/isl_ast_build_private.h
+++ b/polly/lib/External/isl/isl_ast_build_private.h
@@ -203,7 +203,7 @@ __isl_give isl_ast_build *isl_ast_build_clear_local_info(
 	__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/polly/lib/External/isl/isl_ast_codegen.c b/polly/lib/External/isl/isl_ast_codegen.c
index 7f891a0035509..d337c4e4e2f6c 100644
--- a/polly/lib/External/isl/isl_ast_codegen.c
+++ b/polly/lib/External/isl/isl_ast_codegen.c
@@ -743,12 +743,15 @@ static __isl_give isl_set *add_implied_guards(__isl_take isl_set *guard,
 	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 @@ static __isl_give isl_set *add_implied_guards(__isl_take isl_set *guard,
  *
  * 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_graft *set_for_cond_from_set(
  */
 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 @@ static __isl_give isl_ast_graft *refine_generic_bounds(
 	__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 @@ static __isl_give isl_ast_graft *refine_generic_bounds(
 	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 @@ static __isl_give isl_ast_graft *refine_generic_split(
 	__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_graft *refine_generic(
 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 @@ static __isl_give isl_ast_graft *create_node_scaled(
 	__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 @@ static __isl_give isl_ast_graft *create_node_scaled(
 	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 @@ static __isl_give isl_ast_graft *create_node(__isl_take isl_union_map *executed,
 	__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 @@ static __isl_give isl_ast_graft *create_node(__isl_take isl_union_map *executed,
 	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 @@ struct isl_add_nodes_data {
 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 @@ static isl_stat add_nodes(__isl_take isl_basic_set_list *scc, void *user)
 	}
 
 	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 @@ static __isl_give isl_ast_graft_list *generate_sorted_domains(
 {
 	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 @@ static __isl_give isl_ast_graft_list *generate_sorted_domains(
 	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 @@ static __isl_give isl_ast_graft_list *generate_parallel_domains(
 	__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 @@ static __isl_give isl_ast_graft_list *generate_parallel_domains(
 		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 @@ static __isl_give isl_set *explicit_bounds(__isl_take isl_map *map,
 	__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 @@ static int foreach_iteration(__isl_take isl_set *domain,
 	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 @@ static isl_bool has_pure_outer_disjunction(__isl_keep isl_set *domain,
 	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 @@ static isl_bool has_pure_outer_disjunction(__isl_keep isl_set *domain,
 	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 @@ static __isl_give isl_set *extract_disjunction(__isl_take isl_set *domain,
 	__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_only_after(
 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 @@ static __isl_give isl_ast_graft_list *generate_shifted_component_tree(
 		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 int first_offset(struct isl_set_map_pair *domain, int *order, int n,
 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 @@ static __isl_give isl_ast_graft_list *generate_shift_component(
 {
 	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 @@ static __isl_give isl_ast_graft_list *generate_shift_component(
 	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 @@ static __isl_give isl_ast_graft_list *generate_component(
 	__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 @@ static __isl_give isl_ast_graft_list *generate_component(
 	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 @@ static __isl_give isl_ast_graft_list *generate_components(
 	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 @@ static __isl_give isl_ast_graft_list *generate_components(
 	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 @@ error:		list = isl_ast_graft_list_free(list);
 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 @@ static __isl_give isl_ast_graft_list *generate_next_level(
 
 	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/polly/lib/External/isl/isl_ast_graft.c b/polly/lib/External/isl/isl_ast_graft.c
index 7a0998661961c..03e8449d90c60 100644
--- a/polly/lib/External/isl/isl_ast_graft.c
+++ b/polly/lib/External/isl/isl_ast_graft.c
@@ -110,24 +110,24 @@ static isl_bool equal_independent_guards(__isl_keep isl_ast_graft_list *list,
 {
 	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_bool equal_independent_guards(__isl_keep isl_ast_graft_list *list,
 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 @@ static __isl_give isl_ast_graft_list *graft_extend_body(
 	__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 @@ static __isl_give isl_ast_graft_list *graft_extend_body(
 
 	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 @@ __isl_give isl_basic_set *isl_ast_graft_list_extract_shared_enforced(
 {
 	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/polly/lib/External/isl/isl_box.c b/polly/lib/External/isl/isl_box.c
index d7c5ce1552636..d4eb54f3ecb59 100644
--- a/polly/lib/External/isl/isl_box.c
+++ b/polly/lib/External/isl/isl_box.c
@@ -432,6 +432,48 @@ __isl_give isl_fixed_box *isl_set_get_simple_fixed_box_hull(
 	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/polly/lib/External/isl/isl_coalesce.c b/polly/lib/External/isl/isl_coalesce.c
index ba876acbffbf4..e7cefa0dcc47b 100644
--- a/polly/lib/External/isl/isl_coalesce.c
+++ b/polly/lib/External/isl/isl_coalesce.c
@@ -498,7 +498,7 @@ static int number_of_constraints_increases(int i, int j,
  * 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 
diff erent.
- * 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 @@ static enum isl_change coalesce_subset_with_equalities(int i, int j,
 	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 @@ static isl_bool has_nested_div(__isl_keep isl_basic_map *bmap)
  * 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/polly/lib/External/isl/isl_constraint.c b/polly/lib/External/isl/isl_constraint.c
index f69e339ad69a5..4fc7aba8c9b4c 100644
--- a/polly/lib/External/isl/isl_constraint.c
+++ b/polly/lib/External/isl/isl_constraint.c
@@ -574,24 +574,6 @@ __isl_give isl_constraint *isl_constraint_set_constant_si(
 	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/polly/lib/External/isl/isl_id.c b/polly/lib/External/isl/isl_id.c
index 982d9ebb547b8..ab0f75b3693c7 100644
--- a/polly/lib/External/isl/isl_id.c
+++ b/polly/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/polly/lib/External/isl/isl_list_read_templ.c b/polly/lib/External/isl/isl_list_read_templ.c
new file mode 100644
index 0000000000000..25b3478c1a4a8
--- /dev/null
+++ b/polly/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/polly/lib/External/isl/isl_list_templ.c b/polly/lib/External/isl/isl_list_templ.c
index 03bea20a0face..cfb4f33977939 100644
--- a/polly/lib/External/isl/isl_list_templ.c
+++ b/polly/lib/External/isl/isl_list_templ.c
@@ -606,6 +606,14 @@ __isl_give LIST(EL) *FN(FN(LIST(EL),from),EL_BASE)(__isl_take EL *el)
 	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/polly/lib/External/isl/isl_map.c b/polly/lib/External/isl/isl_map.c
index 6b6f3010cf68d..516106cf3a80d 100644
--- a/polly/lib/External/isl/isl_map.c
+++ b/polly/lib/External/isl/isl_map.c
@@ -112,11 +112,32 @@ isl_size isl_map_dim(__isl_keep isl_map *map, enum isl_dim_type type)
 	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 @@ __isl_give isl_map *isl_map_set_tuple_id(__isl_take isl_map *map,
 	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 @@ isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type)
 	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 @@ static __isl_give isl_basic_map *isl_basic_map_swap_vars(
  * 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 @@ __isl_give isl_set *isl_set_from_basic_set(__isl_take isl_basic_set *bset)
 	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 @@ __isl_give isl_basic_set *isl_basic_set_intersect_params(
 	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 @@ __isl_give isl_basic_set *isl_basic_set_intersect_params(
 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 @@ static __isl_give isl_map *map_intersect_internal(__isl_take isl_map *map1,
 		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 @@ __isl_give isl_map *isl_map_universe(__isl_take isl_space *space)
 	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 @@ __isl_give isl_set *isl_set_universe(__isl_take isl_space *space)
 	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 @@ __isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_set *bset,
 	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/polly/lib/External/isl/isl_map_list.c b/polly/lib/External/isl/isl_map_list.c
index cb94c35e512ee..3314fa70a9abc 100644
--- a/polly/lib/External/isl/isl_map_list.c
+++ b/polly/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/polly/lib/External/isl/isl_map_private.h b/polly/lib/External/isl/isl_map_private.h
index 5ddd3c80a29da..c52e835a359e5 100644
--- a/polly/lib/External/isl/isl_map_private.h
+++ b/polly/lib/External/isl/isl_map_private.h
@@ -500,7 +500,7 @@ isl_bool isl_map_align_params_map_map_and_test(__isl_keep isl_map *map1,
 	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/polly/lib/External/isl/isl_map_subtract.c b/polly/lib/External/isl/isl_map_subtract.c
index 66e423baeaac3..6431b3daa9649 100644
--- a/polly/lib/External/isl/isl_map_subtract.c
+++ b/polly/lib/External/isl/isl_map_subtract.c
@@ -643,7 +643,7 @@ __isl_give isl_map *isl_map_subtract_range(__isl_take isl_map *map,
 }
 
 /* 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/polly/lib/External/isl/isl_multi_identity_templ.c b/polly/lib/External/isl/isl_multi_identity_templ.c
index d598d11accc8b..1ffeadf57a460 100644
--- a/polly/lib/External/isl/isl_multi_identity_templ.c
+++ b/polly/lib/External/isl/isl_multi_identity_templ.c
@@ -72,6 +72,16 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),identity_on_domain_space)(
 	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/polly/lib/External/isl/isl_multi_templ.c b/polly/lib/External/isl/isl_multi_templ.c
index 40790c71fcde1..3777024d2e95e 100644
--- a/polly/lib/External/isl/isl_multi_templ.c
+++ b/polly/lib/External/isl/isl_multi_templ.c
@@ -479,6 +479,15 @@ __isl_give MULTI(BASE) *FN(FN(MULTI(BASE),from),LIST(BASE))(
 	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/polly/lib/External/isl/isl_multi_tuple_id_templ.c b/polly/lib/External/isl/isl_multi_tuple_id_templ.c
index 03f74d479176b..87f9fe6b71d88 100644
--- a/polly/lib/External/isl/isl_multi_tuple_id_templ.c
+++ b/polly/lib/External/isl/isl_multi_tuple_id_templ.c
@@ -28,6 +28,18 @@ isl_bool FN(MULTI(BASE),has_tuple_id)(__isl_keep MULTI(BASE) *multi,
 	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 @@ __isl_give isl_id *FN(MULTI(BASE),get_tuple_id)(__isl_keep MULTI(BASE) *multi,
 	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 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),set_tuple_id)(
 	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 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),reset_tuple_id)(
 
 	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/polly/lib/External/isl/isl_multi_zero_space_templ.c b/polly/lib/External/isl/isl_multi_zero_space_templ.c
new file mode 100644
index 0000000000000..8bd027b2ef537
--- /dev/null
+++ b/polly/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/polly/lib/External/isl/isl_multi_zero_templ.c b/polly/lib/External/isl/isl_multi_zero_templ.c
index 2dbc5820727f7..dee3a8fb2646d 100644
--- a/polly/lib/External/isl/isl_multi_zero_templ.c
+++ b/polly/lib/External/isl/isl_multi_zero_templ.c
@@ -49,3 +49,5 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),zero)(__isl_take isl_space *space)
 	isl_space_free(space);
 	return NULL;
 }
+
+#include "isl_multi_zero_space_templ.c"

diff  --git a/polly/lib/External/isl/isl_point.c b/polly/lib/External/isl/isl_point.c
index be41c53b79d83..f7da70644ef0d 100644
--- a/polly/lib/External/isl/isl_point.c
+++ b/polly/lib/External/isl/isl_point.c
@@ -634,6 +634,14 @@ __isl_give isl_set *isl_set_from_point(__isl_take isl_point *pnt)
 	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/polly/lib/External/isl/isl_polynomial.c b/polly/lib/External/isl/isl_polynomial.c
index 5577e07917409..0aac613f0c60e 100644
--- a/polly/lib/External/isl/isl_polynomial.c
+++ b/polly/lib/External/isl/isl_polynomial.c
@@ -4773,6 +4773,33 @@ struct isl_multiplicative_call_data_pw_qpolynomial {
 	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 @@ static isl_bool multiplicative_call_factor_pw_qpolynomial(
 	__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 @@ static __isl_give isl_pw_qpolynomial *compressed_multiplicative_call(
 		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/polly/lib/External/isl/isl_pw_range_tuple_id_templ.c b/polly/lib/External/isl/isl_pw_range_tuple_id_templ.c
new file mode 100644
index 0000000000000..37392f5e9344f
--- /dev/null
+++ b/polly/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/polly/lib/External/isl/isl_schedule_constraints.c b/polly/lib/External/isl/isl_schedule_constraints.c
index 3d92b53592f46..38a3c6f9d369e 100644
--- a/polly/lib/External/isl/isl_schedule_constraints.c
+++ b/polly/lib/External/isl/isl_schedule_constraints.c
@@ -176,11 +176,17 @@ __isl_give isl_schedule_constraints *isl_schedule_constraints_set_context(
 }
 
 /* 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/polly/lib/External/isl/isl_set_list.c b/polly/lib/External/isl/isl_set_list.c
index 2a6749aa13c5d..e505552e2695e 100644
--- a/polly/lib/External/isl/isl_set_list.c
+++ b/polly/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/polly/lib/External/isl/isl_space.c b/polly/lib/External/isl/isl_space.c
index 1aa0f609394a4..fd67a89c65a64 100644
--- a/polly/lib/External/isl/isl_space.c
+++ b/polly/lib/External/isl/isl_space.c
@@ -578,6 +578,24 @@ isl_bool isl_space_has_tuple_id(__isl_keep isl_space *space,
 	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 @@ __isl_give isl_id *isl_space_get_tuple_id(__isl_keep isl_space *space,
 	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 @@ __isl_give isl_space *isl_space_set_tuple_id(__isl_take isl_space *space,
 	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/polly/lib/External/isl/isl_tab_pip.c b/polly/lib/External/isl/isl_tab_pip.c
index b8659e063f633..5a3148b78e783 100644
--- a/polly/lib/External/isl/isl_tab_pip.c
+++ b/polly/lib/External/isl/isl_tab_pip.c
@@ -5934,7 +5934,7 @@ static __isl_give isl_pw_multi_aff *split_domain_pma(
 			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/polly/lib/External/isl/isl_test.c b/polly/lib/External/isl/isl_test.c
index d609442c213f1..4d82f1eba9156 100644
--- a/polly/lib/External/isl/isl_test.c
+++ b/polly/lib/External/isl/isl_test.c
@@ -7833,6 +7833,15 @@ struct isl_vertices_test_data {
 		"[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 @@ int test_sample(isl_ctx *ctx)
 	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;
@@ -9240,133 +9277,6 @@ static int test_curry(isl_ctx *ctx)
 	return 0;
 }
 
-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;
@@ -10813,7 +10723,6 @@ struct {
 	{ "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 @@ struct {
 	{ "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/polly/lib/External/isl/isl_test2.cc b/polly/lib/External/isl/isl_test2.cc
new file mode 100644
index 0000000000000..7b64d6ffaa244
--- /dev/null
+++ b/polly/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/polly/lib/External/isl/isl_test_cpp.cc b/polly/lib/External/isl/isl_test_cpp.cc
index 6d448f04fddf8..d606a21f8abbb 100644
--- a/polly/lib/External/isl/isl_test_cpp.cc
+++ b/polly/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 @@ static void test_ast_build(isl::ctx ctx)
 	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 @@ static void test_ast_build(isl::ctx ctx)
  *  - Schedule trees
  *  - AST generation
  *  - AST expression generation
+ *  - Templated interface
  */
 int main()
 {
@@ -315,6 +337,7 @@ int main()
 	test_schedule_tree(ctx);
 	test_ast_build(ctx);
 	test_ast_build_expr(ctx);
+	test_typed(ctx);
 
 	isl_ctx_free(ctx);
 

diff  --git a/polly/lib/External/isl/isl_test_cpp_failed.sh b/polly/lib/External/isl/isl_test_cpp_failed.sh
new file mode 100755
index 0000000000000..090a89ea842e0
--- /dev/null
+++ b/polly/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/polly/lib/External/isl/isl_test_python.py b/polly/lib/External/isl/isl_test_python.py
index 5373f967e6fdf..443f5a1f4a84d 100755
--- a/polly/lib/External/isl/isl_test_python.py
+++ b/polly/lib/External/isl/isl_test_python.py
@@ -183,7 +183,7 @@ def add(bs):
 	assert(not list[1].is_equal(list[2]))
 
 	def fail(bs):
-		raise "fail"
+		raise Exception("fail")
 
 	caught = False
 	try:
@@ -217,7 +217,7 @@ def not_in_A(s):
 	assert(not us.every_set(not_in_A))
 
 	def fail(s):
-		raise "fail"
+		raise Exception("fail")
 
 	caught = False
 	try:
@@ -289,7 +289,7 @@ def inc_count(node):
 	assert(count[0] == 8)
 
 	def fail_map(node):
-		raise "fail"
+		raise Exception("fail")
 		return node
 	caught = False
 	try:
@@ -318,7 +318,7 @@ def is_not_domain(node):
 	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 inc_count_ast(node, build):
 	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/polly/lib/External/isl/isl_union_map.c b/polly/lib/External/isl/isl_union_map.c
index bd93dcc716999..2ea129b514400 100644
--- a/polly/lib/External/isl/isl_union_map.c
+++ b/polly/lib/External/isl/isl_union_map.c
@@ -523,11 +523,27 @@ __isl_give isl_union_map *isl_union_map_from_map(__isl_take isl_map *map)
 	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 @@ __isl_give isl_map *isl_map_from_union_map(__isl_take isl_union_map *umap)
 	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/polly/lib/External/isl/isl_union_templ.c b/polly/lib/External/isl/isl_union_templ.c
index 9439d9be7d8eb..d16ccd94aa3ff 100644
--- a/polly/lib/External/isl/isl_union_templ.c
+++ b/polly/lib/External/isl/isl_union_templ.c
@@ -543,6 +543,14 @@ __isl_give UNION *FN(FN(UNION,from),BASE)(__isl_take PART *part)
 	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/polly/lib/External/isl/isl_val.c b/polly/lib/External/isl/isl_val.c
index dc6f71495aa50..3744aa74d082b 100644
--- a/polly/lib/External/isl/isl_val.c
+++ b/polly/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/polly/lib/External/isl/isl_vertices.c b/polly/lib/External/isl/isl_vertices.c
index 120deab4ba78d..fd1a2ee088ee4 100644
--- a/polly/lib/External/isl/isl_vertices.c
+++ b/polly/lib/External/isl/isl_vertices.c
@@ -324,12 +324,11 @@ static isl_bool can_select(__isl_keep isl_basic_set *bset, int level,
  * 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);
 
@@ -343,6 +342,37 @@ static __isl_give isl_vertices *lower_dim_vertices(
 	return vertices;
 }
 
+/* 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
@@ -352,10 +382,23 @@ static __isl_give isl_vertices *lower_dim_vertices(
  * 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 @@ __isl_give isl_vertices *isl_basic_set_compute_vertices(
 	struct isl_tab *tab;
 	int level;
 	int init;
+	isl_size n_eq;
 	isl_size nvar;
 	int *selection = NULL;
 	int selected;
@@ -386,6 +430,8 @@ __isl_give isl_vertices *isl_basic_set_compute_vertices(
 	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 @@ __isl_give isl_vertices *isl_basic_set_compute_vertices(
 		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 @@ __isl_give isl_vertices *isl_basic_set_compute_vertices(
 	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 @@ __isl_give isl_vertices *isl_basic_set_compute_vertices(
 	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 @@ __isl_give isl_vertices *isl_basic_set_compute_vertices(
 		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 @@ __isl_give isl_vertices *isl_basic_set_compute_vertices(
 		}
 		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_give isl_vertices *isl_basic_set_compute_vertices(
 
 	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 @@ __isl_give isl_vertices *isl_basic_set_compute_vertices(
 	free(selection);
 	free(snap);
 	isl_tab_free(tab);
-	isl_basic_set_free(bset);
+	isl_basic_set_free(copy);
 	return NULL;
 }
 
@@ -862,6 +916,7 @@ static __isl_give isl_vertices *compute_chambers(__isl_take isl_basic_set *bset,
 {
 	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 @@ static __isl_give isl_vertices *compute_chambers(__isl_take isl_basic_set *bset,
 		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/polly/lib/External/isl/ltmain.sh b/polly/lib/External/isl/ltmain.sh
index 0cb7f90d3bd7a..48cea9b0e5bd4 100644
--- a/polly/lib/External/isl/ltmain.sh
+++ b/polly/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 at 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 @@ package_revision=2.4.6
 # 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 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/>.
+# 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.
 
-# Please report bugs or propose patches to gary at gnu.org.
+# Please report bugs or propose patches to:
+# <https://github.com/gnulib-modules/bootstrap/issues>
 
 
 ## ------ ##
@@ -140,9 +131,6 @@ do
 	fi"
 done
 
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
 # Make sure IFS has a sensible default
 sp=' '
 nl='
@@ -159,6 +147,26 @@ if test "${PATH_SEPARATOR+set}" != set; then
 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 @@ test -z "$SED" && {
     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 @@ test -z "$GREP" && {
     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 @@ EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
 # 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 @@ if test yes = "$_G_HAVE_PLUSEQ_OP"; then
   {
     $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_relative_path ()
 }
 
 
-# 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
-        *[\\\`\"\$]*)
-	  _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"
+    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
 
-      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\"
+      # Quote for eval.
+      case $func_quote_portable_result in
+        *[\\\`\"\$]*)
+          case $func_quote_portable_result in
+            *[\[\*\?]*)
+              func_quote_portable_result=`$ECHO "$func_quote_portable_result" \
+                  | $SED "$sed_quote_subst"`
+              break
+              ;;
+          esac
+
+          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 ()
-{
-    $debug_cmd
+# 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
 
-    case $1 in
-      *[\\\`\"]*)
-	_G_arg=`$ECHO "$1" | $SED \
-	    -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
-      *)
-        _G_arg=$1 ;;
+
+# 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 ()
+{
+    _G_quote_expand=false
+    case ,$1, in
+      *,expand,*)
+        _G_quote_expand=:
+        ;;
     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\"
+    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_for_expand_result=$_G_arg
+
+# 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 @@ func_show_eval ()
     _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 @@ func_show_eval_locale ()
     _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 @@ func_lt_ver ()
 # 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 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.
-
-# 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.
+# 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.
 
-# 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:
+# <https://github.com/gnulib-modules/bootstrap/issues>
 
-# Please report bugs or propose patches to gary at gnu.org.
+# Set a version string for this script.
+scriptversion=2018-07-24.06; # UTC
 
 
 ## ------ ##
@@ -1415,7 +1533,7 @@ scriptversion=2015-10-07.11; # UTC
 #
 # 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 @@ scriptversion=2015-10-07.11; # UTC
 # 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 @@ fatal_help="Try '\$progname --help' for more information."
 ## ------------------------- ##
 
 # 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_add_hook ()
 
 # 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_remove_hook ()
 }
 
 
+# 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 @@ func_run_hooks ()
 {
     $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 @@ func_run_hooks ()
 ## --------------- ##
 
 # 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 @@ func_run_hooks ()
 #        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 @@ func_run_hooks ()
 #
 #        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 @@ func_run_hooks ()
 #                         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 @@ func_run_hooks ()
 #
 #        $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 @@ func_options_finish ()
 {
     $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 @@ func_options ()
 {
     $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 @@ func_options ()
 # 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 @@ func_options_prep ()
     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 @@ func_parse_options ()
 {
     $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 @@ func_parse_options ()
 
         --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 @@ func_parse_options ()
                       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 @@ func_parse_options ()
                       ;;
       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 @@ func_validate_options ()
 {
     $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_missing_arg ()
 
 # 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 @@ then
 
       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_usage_message ()
 # 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
-        }
-        :go
-        /^# Written by /,/# warranty; / {
-          s|^# ||
-          s|^# *$||
-          s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
-          p
+        /^# Written by /!b
+        s|^# ||; p; n
+
+        :fwd2blnk
+        /./ {
+          n
+          b fwd2blnk
         }
-        /^# Written by / {
-          s|^# ||
-          p
+        p; n
+
+        :holdwrnt
+        s|^# ||
+        s|^# *$||
+        /^Copyright /!{
+          /./H
+          n
+          b holdwrnt
         }
-        /^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 @@ func_version ()
 # 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 @@ include the following information:
        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 @@ fi
 # 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 @@ libtool_options_prep ()
 
     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 @@ libtool_parse_options ()
 
     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 @@ libtool_validate_options ()
     }
 
     # 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 @@ func_mode_compile ()
       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 @@ compiler."
 
     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 @@ func_mode_install ()
        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 @@ func_mode_install ()
 
     # 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 @@ func_mode_install ()
       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 @@ func_mode_install ()
 
     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 @@ func_mode_install ()
 	        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 @@ else
   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 @@ func_fallback_echo ()
 \$1
 _LTECHO_EOF'
 }
-    ECHO=\"$qECHO\"
+    ECHO=$qECHO
   fi
 
 # Very basic option parsing. These options are (a) specific to
@@ -6703,9 +6826,9 @@ func_mode_link ()
     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 @@ func_mode_link ()
 	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 @@ func_mode_link ()
 	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 @@ func_mode_link ()
 
       # -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 @@ func_mode_link ()
       # -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 @@ func_mode_link ()
 	  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 @@ func_mode_link ()
       *)
 	# 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 @@ func_mode_link ()
 	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 @@ func_mode_link ()
 	    # 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 @@ func_mode_link ()
 	    revision=$number_minor
 	    lt_irix_increment=no
 	    ;;
-	  *)
-	    func_fatal_configuration "$modename: unknown library version type '$version_type'"
-	    ;;
 	  esac
 	  ;;
 	no)
@@ -10037,8 +10152,8 @@ EOF
 	    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 @@ EOF
 	  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 @@ EOF
 	  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 @@ EOF
 	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/polly/lib/External/isl/m4/ax_detect_clang.m4 b/polly/lib/External/isl/m4/ax_detect_clang.m4
index 85920a21a2a1f..e5cc7aaa438ca 100644
--- a/polly/lib/External/isl/m4/ax_detect_clang.m4
+++ b/polly/lib/External/isl/m4/ax_detect_clang.m4
@@ -75,7 +75,7 @@ CC="$SAVE_CC"
 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 @@ AC_TRY_COMPILE([
 	#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 @@ AC_TRY_COMPILE([
 	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/polly/lib/External/isl/m4/libtool.m4 b/polly/lib/External/isl/m4/libtool.m4
index a6d21ae56ea74..2b73e38446de2 100644
--- a/polly/lib/External/isl/m4/libtool.m4
+++ b/polly/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 @@ esac
 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 @@ int forced_loaded() { return 2;}
 _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 @@ need_locks=$enable_libtool_lock
 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 @@ m4_defun([_LT_CMD_STRIPLIB],
 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 @@ m4_if([$1], [],[
     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 @@ m4_if([$1], [],[
     ;;
 
   *)
-    # 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 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   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 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   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 @@ for ac_symprfx in "" "_"; do
   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 @@ _LT_EOF
   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 @@ m4_if([$1], [CXX], [
 	    ;;
 	esac
 	;;
-      netbsd* | netbsdelf*-gnu)
+      netbsd*)
 	;;
       *qnx* | *nto*)
         # QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -4704,12 +4713,6 @@ m4_if([$1], [CXX], [
 	_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 @@ m4_if([$1], [CXX], [
     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 @@ m4_if([$1], [CXX], [
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
-    cl*)
+    cl* | icl*)
       _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
       ;;
     *)
@@ -4954,9 +4957,6 @@ m4_if([$1], [CXX], [
       ;;
     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 @@ dnl Note also adjust exclude_expsyms for C++ above.
 
   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 @@ _LT_EOF
 	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 @@ _LT_EOF
       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 @@ _LT_EOF
 	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 @@ _LT_EOF
 
     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 @@ _LT_EOF
           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 @@ _LT_EOF
 	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 @@ _LT_EOF
       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 @@ _LT_EOF
 	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 @@ if test yes != "$_lt_caught_CXX_error"; then
       # 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 @@ if test yes != "$_lt_caught_CXX_error"; then
 
       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 @@ if test yes != "$_lt_caught_CXX_error"; then
 	  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 @@ if test yes != "$_lt_caught_CXX_error"; then
             # 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 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # 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 @@ if test yes != "$_lt_caught_CXX_error"; then
 	      # 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 @@ if test yes != "$_lt_caught_CXX_error"; then
 	        # 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 @@ if test yes != "$_lt_caught_CXX_error"; then
 	        # 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/polly/lib/External/isl/m4/ltoptions.m4 b/polly/lib/External/isl/m4/ltoptions.m4
index 94b082976667c..07421d929ef08 100644
--- a/polly/lib/External/isl/m4/ltoptions.m4
+++ b/polly/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/polly/lib/External/isl/m4/ltsugar.m4 b/polly/lib/External/isl/m4/ltsugar.m4
index 48bc9344a4d66..3985c5683a7d8 100644
--- a/polly/lib/External/isl/m4/ltsugar.m4
+++ b/polly/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/polly/lib/External/isl/m4/ltversion.m4 b/polly/lib/External/isl/m4/ltversion.m4
index fa04b52a3bf86..7f9a3ada9766c 100644
--- a/polly/lib/External/isl/m4/ltversion.m4
+++ b/polly/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/polly/lib/External/isl/m4/lt~obsolete.m4 b/polly/lib/External/isl/m4/lt~obsolete.m4
index c6b26f88f6c3c..54ea1c421c9d0 100644
--- a/polly/lib/External/isl/m4/lt~obsolete.m4
+++ b/polly/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/polly/lib/External/isl/missing b/polly/lib/External/isl/missing
index 625aeb11897a2..8d0eaad250fc1 100755
--- a/polly/lib/External/isl/missing
+++ b/polly/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 at iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify

diff  --git a/polly/lib/External/isl/polyhedron_remove_redundant_equalities.c b/polly/lib/External/isl/polyhedron_remove_redundant_equalities.c
new file mode 100644
index 0000000000000..2de47acdc2060
--- /dev/null
+++ b/polly/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/polly/lib/External/isl/py-compile b/polly/lib/External/isl/py-compile
old mode 100644
new mode 100755
index 9f8baf7ab8ea6..e56d98d6e9f7d
--- a/polly/lib/External/isl/py-compile
+++ b/polly/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 @@ else
     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 @@ for file in files.split():
 	    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 @@ for file in files.split():
 	    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/polly/lib/External/isl/test-driver b/polly/lib/External/isl/test-driver
index b8521a482e2b7..9759384aa72c4 100755
--- a/polly/lib/External/isl/test-driver
+++ b/polly/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 @@ print_usage ()
 {
   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
 }
 


        


More information about the llvm-commits mailing list