int ?=?( int*, int );
float ?=?( float*, float );
int * ?=?( int **, int * );
float * ?=?( float **, float * );
char ?=?( char*, char );
void (* ?=?( void (**)(void), void (*)(void) ))(void);

void g1() {
	forall( otype T ) T f( T );
	void f( int );
	void h( void (*p)(void) );

	int x;
	void (*y)(void);
	char z;
	float w;

	f( x );
	f( y );
	f( z );
	f( w );
	h( f( y ) );
}

void g2() {
	forall( otype T ) void f( T, T );
	forall( otype T, otype U ) void f( T, U );

	int x;
	float y;
	int *z;
	float *w;

	f( x, y );
	f( z, w );
	f( x, z );
}

typedef forall ( otype T ) int (*f)( int );

forall( otype T )
void swap( T left, T right ) {
	T temp = left;
	left = right;
	right = temp;
}

trait sumable( otype T ) {
	const T 0;
	T ?+?(T, T);
	T ?++(T);
	[T] ?+=?(T,T);
};

otype T1 | { const T1 0; T1 ?+?(T1, T1); T1 ?++(T1); [T1] ?+=?(T1,T1); },
	T2(otype P1, otype P2 ),
	T3 | sumable(T3);

otype T2(otype P1, otype P2) | sumable(T2(P1,P2)) = struct { P1 i; P2 j; };

T2(int, int) w1;
typedef T2(int, int) w2;
w2 g2;
otype w3 = T2(int, int);
w3 g3;

forall( otype T | sumable( T ) )
T sum( int n, T a[] ) {
	T total = 0;
	int i;
	for ( i = 0; i < n; i += 1 )
		total = total + a[i];
	return total;
}

forall( otype T | { const T 0; T ?+?(T, T); T ?++(T); [T] ?+=?(T,T); } )
T twice( T t ) {
	return t + t;
}

forall( otype T | { const T 0; int ?!=?(T, T); int ?<?(T, T); } )
T min( T t1, T t2 ) {
	return t1 < t2 ? t1 : t2;
}

int main() {
	int x = 1, y = 2, a[10];
	float f;

	swap( x, y );
	twice( x );
	f = min( 4.0, 3.0 );
	sum( 10, a );
}

// Local Variables: //
// tab-width: 4 //
// End: //
