/*
 * complex operation program copyright (C) 2009 - 2013 H.Niwa
 */

/*
 * 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 2, 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.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <errno.h>
#include <math.h>

#if !defined(__MINGW32__) && !defined(__sun)  
#ifdef __CYGWIN__
#include <ieeefp.h>
#endif
#endif

#include <string>
#include <cmath>
#include <complex>

#include "syserr.h"

#include "bin_node.h"
#include "gc.h"
#include "var.h"
#include "pred.h"
#include "context.h"
#include "unify.h"
#include "builtin.h"
#include "sysmodule.h"
#include "expression.h"
#include "let.h"
#include "module.h"
#include "help.h"

#include "complx.h"

#if defined(__CYGWIN__) && !defined(__MINGW32__)
#define sinl(x)		sin(x)
#define cosl(x)		cos(x)
#define tanl(x)		tan(x)
#define asinl(x)	asin(x)
#define acosl(x)	acos(x)
#define atanl(x)	atan(x)
#define sinhl(x)	sinh(x)
#define coshl(x)	cosh(x)
#define tanhl(x)	tanh(x)
#define asinhl(x)	asinh(x)
#define acoshl(x)	acosh(x)
#define atanhl(x)	atanh(x)

#define logl(x)		log(x)
#define log10l(x)	log10(x)
#define expl(x)		exp(x)
#define powl(x, y)	pow(x, y)
#define sqrtl(x)	sqrt(x)
#define fabsl(x)	fabs(x)

#define floorl(x)	floor(x)
#define ceill(x)	ceil(x)
#define truncl(x)	trunc(x)

#endif


#ifndef __MINGW32__
int isInf(Context* cx, Node* n, List* module);
int isNan(Context* cx, Node* n, List* module);
int Finite(Context* cx, Node* n, List* module);
#endif

int CReal(Context* cx, Node* goalscar, List* module);
int CImage(Context* cx, Node* goalscar, List* module);

int CAbs(Context* cx, Node* goalscar, List* module);
int CArg(Context* cx, Node* goalscar, List* module);
int CNorm(Context* cx, Node* goalscar, List* module);
int CConj(Context* cx, Node* goalscar, List* module);
int CPolar(Context* cx, Node* goalscar, List* module);

int CSin(Context* cx, Node* goalscar, List* module);
int CCos(Context* cx, Node* goalscar, List* module);
int CTan(Context* cx, Node* goalscar, List* module);

int CASin(Context* cx, Node* goalscar, List* module);
int CACos(Context* cx, Node* goalscar, List* module);
int CATan(Context* cx, Node* goalscar, List* module);

int CSinh(Context* cx, Node* goalscar, List* module);
int CCosh(Context* cx, Node* goalscar, List* module);
int CTanh(Context* cx, Node* goalscar, List* module);

int CASinh(Context* cx, Node* goalscar, List* module);
int CACosh(Context* cx, Node* goalscar, List* module);
int CATanh(Context* cx, Node* goalscar, List* module);

int CLog(Context* cx, Node* goalscar, List* module);
int CLog10(Context* cx, Node* goalscar, List* module);

int CPow(Context* cx, Node* goalscar, List* module);
int CSqrt(Context* cx, Node* goalscar, List* module);

int CExp(Context* cx, Node* goalscar, List* module);
int CExp2(Context* cx, Node* goalscar, List* module);
int CExp10(Context* cx, Node* goalscar, List* module);

int Sin(Context* cx, Node* goalscar, List* module);
int Cos(Context* cx, Node* goalscar, List* module);
int Tan(Context* cx, Node* goalscar, List* module);
int ASin(Context* cx, Node* goalscar, List* module);
int ACos(Context* cx, Node* goalscar, List* module);
int ATan(Context* cx, Node* goalscar, List* module);
int Sinh(Context* cx, Node* goalscar, List* module);
int Cosh(Context* cx, Node* goalscar, List* module);
int Tanh(Context* cx, Node* goalscar, List* module);
int ASinh(Context* cx, Node* goalscar, List* module);
int ACosh(Context* cx, Node* goalscar, List* module);
int ATanh(Context* cx, Node* goalscar, List* module);
int PI(Context* cx, Node* goalscar, List* module);
int E(Context* cx, Node* goalscar, List* module);
int Log(Context* cx, Node* goalscar, List* module);
int Log10(Context* cx, Node* goalscar, List* module);
int Exp(Context* cx, Node* goalscar, List* module);
int Exp2(Context* cx, Node* goalscar, List* module);
int Exp10(Context* cx, Node* goalscar, List* module);
int Pow(Context* cx, Node* goalscar, List* module);
int Sqrt(Context* cx, Node* goalscar, List* module);
int Abs(Context* cx, Node* goalscar, List* module);

int ATan2(Context* cx, Node* goalscar, List* module);

int Int(Context* cx, Node* goalscar, List* module);
int Floor(Context* cx, Node* goalscar, List* module);
int Ceil(Context* cx, Node* goalscar, List* module);
int Trunc(Context* cx, Node* goalscar, List* module);




int CReal(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("real: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <real VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("real: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <real VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(f));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


int CImage(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("image: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <image VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("image: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toImage(f))) {
		syserr("usage : <image VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(f));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}



int CAbs(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <abs VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("abs: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <abs VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("abs: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <abs VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(abs(c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


int CArg(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("arg: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <arg VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("arg: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <arg VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(arg(c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


int CNorm(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <norm VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("norm: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <norm VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("norm: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <norm VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(norm(c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


int CConj(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <conj VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("conj: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <conj VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("conj: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <conj VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(conj(c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int CPolar(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 3) {
		syserr("usage : <polar VAR VAL1 VAL2> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag1 = goalscar->Cdr()->Cdr()->Car()->Val();
	Node* ag2 = goalscar->Cdr()->Cdr()->Cdr()->Car()->Val();
	long double	f1, f2;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("polar: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <polar VAR VAL1 VAL2> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag1, goalscar, module)) <= 0) {
		syserr("polar: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag1->kind() != ATOM) || (!((Atom*)ag1)->toFloat(f1))) {
		syserr("usage : <polar VAR VAL1 VAL2> \n");
		return 0;
	}

	if ((rn = FuncArg(cx, ag2, goalscar, module)) <= 0) {
		syserr("polar: failed in the evaluation of the argument. \n");
		return 0;
	}


	if ((ag2->kind() != ATOM) || (!((Atom*)ag2)->toFloat(f2))) {
		syserr("usage : <polar VAR VAL1 VAL2> \n");
		return 0;
	}
	if (f1 < 0) {
		return 0;
	}

	std::complex<long double> p =
		std::complex<long double>(f1*cos(f2),f1*sin(f2));

	Node* env = Nil->Cons(Nil);

	SetEnv(env, v);
	((Undef*)v)->Set(mka(p));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}



int CSin(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <sin VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("sin: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <sin VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("sin: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <sin VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(sin(c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


int CCos(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <cos VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("cos: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <cos VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("cos: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <cos VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(cos(c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int CTan(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <tan VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("tan: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <tan VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("tan: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <tan VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(tan(c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}



int CASin(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <asin VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c, z, i(0,1), n1(1,0);

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("asin: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <asin VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("asin: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(z))) {
		syserr("usage : <asin VAR VAL> \n");
		return 0;
	}

	c = - i * log(i*z+sqrt(-z*z+n1));
		
	Node* env = Nil->Cons(Nil);

	SetEnv(env, v);
	((Undef*)v)->Set(mka(c));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


int CACos(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <acos VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c, z, i(0,1), n1(1,0);

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("acos: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <acos VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("acos: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(z))) {
		syserr("usage : <acos VAR VAL> \n");
		return 0;
	}
	
	c = -i* log(z+sqrt(z*z-n1));

	Node* env = Nil->Cons(Nil);

	SetEnv(env, v);
	((Undef*)v)->Set(mka(c));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


int CATan(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <atan VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c, z, i(0,1), n1(1,0), n2(2,0);

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("atan: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <atan VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("atan: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(z))) {
		syserr("usage : <atan VAR VAL> \n");
		return 0;
	}
	
	c = -i*log((i*z+n1)/(-i*z+n1))/n2;

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(c));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}



int CSinh(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <sinh VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("sinh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <sinh VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("sinh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <sinh VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(sinh(c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


int CCosh(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <cosh VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("cosh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <cosh VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("cosh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <cosh VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(cosh(c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


int CTanh(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <tanh VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("tanh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <tanh VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("tanh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <tanh VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(tanh(c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}



int CASinh(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <asinh VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c, z, i(0,1), n1(1,0);

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("asinh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <asinh VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("asinh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(z))) {
		syserr("usage : <asinh VAR VAL> \n");
		return 0;
	}

	c = log(z+sqrt(z*z+n1));
		
	Node* env = Nil->Cons(Nil);

	SetEnv(env, v);
	((Undef*)v)->Set(mka(c));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


int CACosh(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <acosh VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();

	std::complex<long double> c, z, i(0,1), n1(1,0);

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("acosh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <acosh VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("acosh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(z))) {
		syserr("usage : <acosh VAR VAL> \n");
		return 0;
	}

	c = log(z + sqrt(z*z - n1)); 

	Node* env = Nil->Cons(Nil);

	SetEnv(env, v);
	((Undef*)v)->Set(mka(c));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


int CATanh(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <atanh VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c, z, i(0,1), n1(1,0), n2(2,0);

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("atanh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <atanh VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("atanh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(z))) {
		syserr("usage : <atanh VAR VAL> \n");
		return 0;
	}
	
	c = log((n1+z)/(n1-z))/n2;

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(c));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}



int CLog(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <log VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("log: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <log VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("log: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <log VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(log(c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int CLog10(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <log10 VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("log10: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <log10 VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("log10: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <log10 VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(log10(c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}



int CPow(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 3) {
		syserr("usage : <pow VAR VAL1 VAL2> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag1 = goalscar->Cdr()->Cdr()->Car()->Val();
	Node* ag2 = goalscar->Cdr()->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c1, c2;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("pow: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <pow VAR VAL1 VAL2> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag1, goalscar, module)) <= 0) {
		syserr("pow: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag1->kind() != ATOM) || (!((Atom*)ag1)->toComplex(c1))) {
		syserr("usage : <pow VAR VAL1 VAL2> \n");
		return 0;
	}

	if ((rn = FuncArg(cx, ag2, goalscar, module)) <= 0) {
		syserr("pow: failed in the evaluation of the argument. \n");
		return 0;
	}


	if ((ag2->kind() != ATOM) || (!((Atom*)ag2)->toComplex(c2))) {
		syserr("usage : <pow VAR VAL1 VAL2> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(pow(c1, c2)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int CSqrt(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <sqrt VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("sqrt: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <sqrt VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("sqrt: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <sqrt VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(sqrt(c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}



int CExp(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <exp VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("exp: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <exp VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("exp: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <exp VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(exp(c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int CExp2(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <exp2 VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c, c2(2.0, 0.0);
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("exp2: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <exp2 VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("exp2: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <exp2 VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(pow(c2, c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int CExp10(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <exp10 VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	std::complex<long double>	c, c10(10.0, 0.0);
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("exp10: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <exp10 VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("exp10: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toComplex(c))) {
		syserr("usage : <exp10 VAR VAL> \n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(pow(c10, c)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int Sin(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <sin VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("sin: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <sin VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("sin: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <sin VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)sinl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


int Cos(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <cos VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("cos: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <cos VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("cos: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <cos VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)cosl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int Tan(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <tan VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("tan: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <tan VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("tan: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <tan VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)tanl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int ASin(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <asin VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;
	
	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("asin: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <asin VAR VAL> \n");
		return 0;
	}

	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("asin: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <asin VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)asinl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int ACos(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <acos VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("acos: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <acos VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("acos: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <acos VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)acosl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int ATan(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <atan VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("atan: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <atan VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("atan: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <atan VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)atanl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int ATan2(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 3) {
		syserr("usage : <atan2 VAR VAL1 VAL2> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag1 = goalscar->Cdr()->Cdr()->Car()->Val();
	Node* ag2 = goalscar->Cdr()->Cdr()->Cdr()->Car()->Val();
	long double f1, f2;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("atan2: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <atan2 VAR VAL1 VAL2> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag1, goalscar, module)) <= 0) {
		syserr("atan2: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag1->kind() != ATOM) || (!((Atom*)ag1)->toFloat(f1))) {
		syserr("usage : <atan2 VAR VAL1 VAL2> \n");
		return 0;
	}

	if ((rn = FuncArg(cx, ag2, goalscar, module)) <= 0) {
		syserr("atan2: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag2->kind() != ATOM) || (!((Atom*)ag2)->toFloat(f2))) {
		syserr("usage : <atan2 VAR VAL1 VAL2> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)atan2(f1, f2)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int Sinh(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <sinh VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("sinh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <sinh VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("sinh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <sinh VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)sinhl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


int Cosh(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <cosh VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("cosh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <cosh VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("cosh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <cosh VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)coshl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int Tanh(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <tanh VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("tanh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("tanh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <tanh VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)tanhl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int ASinh(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <asinh VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("asinh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <asinh VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("asinh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <asinh VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)asinhl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int ACosh(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <acosh VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("acosh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <acosh VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("acosh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <acosh VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)acoshl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int ATanh(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <atanh VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("atanh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <atanh VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("atanh: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <atanh VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)atanhl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int PI(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 1) {
		syserr("usage : <PI VAR> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("PI: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <PI VAR> \n");
		return 0;
	}
	
	long double pi = atanl(1.0)*4.0;

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(pi));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int E(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 1) {
		syserr("usage : <e VAR> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("E: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <e VAR> \n");
		return 0;
	}
	
	long double e = expl(1);

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka(e));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int Log(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <log VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("log: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <log VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("log: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <log VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)logl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int Log10(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <log10 VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("log10: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <log10 VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("log10: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <log10 VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)log10l(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}



int Exp(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <exp VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("exp: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <exp VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("exp: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <exp VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)expl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int Pow(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 3) {
		syserr("usage : <pow VAR VAL1 VAL2> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag1 = goalscar->Cdr()->Cdr()->Car()->Val();
	Node* ag2 = goalscar->Cdr()->Cdr()->Cdr()->Car()->Val();
	long double f1, f2;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("pow: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <pow VAR VAL1 VAL2> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag1, goalscar, module)) <= 0) {
		syserr("pow: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag1->kind() != ATOM) || (!((Atom*)ag1)->toFloat(f1))) {
		syserr("usage : <pow VAR VAL1 VAL2> \n");
		return 0;
	}


	if ((rn = FuncArg(cx, ag2, goalscar, module)) <= 0) {
		syserr("pow: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag2->kind() != ATOM) || (!((Atom*)ag2)->toFloat(f2))) {
		syserr("usage : <pow VAR VAL1 VAL2> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)powl(f1, f2)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int Sqrt(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <sqrt VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("sqrt: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <sqrt VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("sqrt: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <sqrt VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)sqrtl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int Abs(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <abs VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("abs: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <abs VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("abs: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <abs VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)fabsl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}


int Int(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <int VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("int: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <int VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("int: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <int VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long long)f));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int Floor(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <floor VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("floor: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <floor VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("floor: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <floor VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)floorl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int Ceil(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <ceil VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("ceil: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <ceil VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("ceil: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <ceil VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)ceill(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int Trunc(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 2) {
		syserr("usage : <trunc VAR VAL> \n");
		return 0;
	}

	Node* v = goalscar->Cdr()->Car()->Val();
	Node* ag = goalscar->Cdr()->Cdr()->Car()->Val();
	long double f;

	int rn;

	if ((rn = FuncArg(cx, v, goalscar, module)) <= 0) {
		syserr("trunc: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (v->kind() != UNDEF) {
		syserr("usage : <trunc VAR VAL> \n");
		return 0;
	}
	
	if ((rn = FuncArg(cx, ag, goalscar, module)) <= 0) {
		syserr("trunc: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((ag->kind() != ATOM) || (!((Atom*)ag)->toFloat(f))) {
		syserr("usage : <trunc VAR VAL> \n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);


	SetEnv(env, v);
	((Undef*)v)->Set(mka((long double)truncl(f)));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

#if !defined(__MINGW32__) && !defined(__sun)
int isInf(Context* cx, Node* n, List* module)
{
	Node* goalscar = n;
	long double	d;
	
	n = n->Cdr()->Val();

	if (ListLength(n) != 1) {
		syserr("usage : <isinf VAL> \n");
		return 0;
	}

	int rn;

	if ((rn = FuncArg(cx, n, goalscar, module)) <= 0) {
		syserr("isinf: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (n->Car()->kind() != ATOM) {
		syserr("usage : <isinf VAL> \n");
		return 0;
	}
	if (((Atom*)(n->Car()))->toFloat(d)) {
		if (isinf(d) == 1) {
			return 1;
		} else {
			return -1;
		}
	} else {
		syserr("usage : <isinf VAL> \n");
		return 0;
	}
}

int isNan(Context* cx, Node* n, List* module)
{
	Node* goalscar = n;
	long double	d;
	
	n = n->Cdr()->Val();

	if (ListLength(n) != 1) {
		syserr("usage : <isnan VAL> \n");
		return 0;
	}

	int rn;

	if ((rn = FuncArg(cx, n, goalscar, module)) <= 0) {
		syserr("isnan: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (n->Car()->kind() != ATOM) {
		syserr("usage : <isnan VAL> \n");
		return 0;
	}
	if (((Atom*)(n->Car()))->toFloat(d)) {
		if (isnan(d) == 1) {
			return 1;
		} else {
			return -1;
		}
	} else {
		syserr("usage : <isnan VAL> \n");
		return 0;
	}
}

int Finite(Context* cx, Node* n, List* module)
{
	Node* goalscar = n;
	long double	d;
	
	n = n->Cdr()->Val();

	if (ListLength(n) != 1) {
		syserr("usage : <finite VAL> \n");
		return 0;
	}

	int rn;

	if ((rn = FuncArg(cx, n, goalscar, module)) <= 0) {
		syserr("finite: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (n->Car()->kind() != ATOM) {
		syserr("usage : <finite VAL> \n");
		return 0;
	}
	if (((Atom*)(n->Car()))->toFloat(d)) {
		if (finite(d) == 1) {
			return 1;
		} else {
			return -1;
		}
	} else {
		syserr("usage : <finite VAL> \n");
		return 0;
	}
}
#endif

