
/**
NAME
	String module

SYNOPSIS

AUTHOR
	Koji Hara, Shintaro Kudo

HISTORY
	2004/05/31(Mon)
		replace
	2004/05/12(Wed)
		split join concat
	.. 2006/01/12(Thu)
		substring str_of_int int_of_str str_of_float float_of_str
	2006/07/02(Sun)
		length, reverse (by inui)
	2006/07/25(Tue)
		string.join に空リストが渡されたら空文字列を返すようにした by inui

COMMENT
	文字列アトムの表現方法は、
	"abc"
	[:abc:]
	の二種類があり、後者は改行が入っても良い。
	'abc'
	は、あくまでアトムの名前であり文字列ではないが、
	昔の名残で混同されていることがあるので注意。
*/

//気になったこと
//1. int_to_strは紛らわしい。文字コードから変換するんだからchar_of_intかな

{
module(str).

H=str.from(X) :- unary(X) | '$callback'('string_make', X, H).

//H=str.t(Str, Times) :- unary(Str), int(Times) |
//	t_s0(Str, Times, 1, "").
//H=t_s0(Str, Times, I, Result) :- int(Times), I0=I*2 |
//	t_s1(str.t(Str, 2), Times, I0, Result).
//H=t_s1(Str, Times, I, Result) :- int(Times), I0=I*2 |
//	t_s1(str.t(Str, 2), Times, I0, Result).

// /**
//  * str.times(+Str, +Times, -Res)
//  *
//  * 与えられた文字列を指定回数繰り返し連結した文字列を返します。
//  * @param +Str 繰り返す文字列
//  * @param +Times 繰り返す回数
//  * @param -Res 結果(文字列)
//  * @example r=str.times("ab", 5)  ==>  r="ababababab"
//  */
// H=str.times(Str, Times) :-
// 	str(Str), int(Times) | H=[:/*inline*/
// 	StrBuffer b = new StrBuffer(((StrFunctor)me.nthAtom(0).getFunctor()).strValue());
// 	StrBuffer r = new StrBuffer("");
// 	int times = ((IntegerFunctor)me.nthAtom(1).getFunctor()).intValue();
// 	for(int i=1;i<=times;i<<=1, b.append(b)) {
// 		if((i&times)>0) r.append(b);
// 	}
// 	Atom result = mem.newAtom(new StrFunctor(r.toStr()));
// 	mem.relink(result, 0, me, 2);
// 	me.nthAtom(0).remove();
// 	me.nthAtom(1).remove();
// 	me.remove();
// 	:](Str, Times).

// /**
//  * str.replace(+Str, +Regexp, +Replacement, -Res):
//  * 
//  * 与えられた文字列の指定されたパターン文字列にマッチする部分を指定文字列で置き換えます。
//  * @param +Str 元の文字列
//  * @param +Regexp パターン文字列(正規表現)
//  * @param -Res 結果 (パターン文字列が変だったときは元の文字列を返す)
//  */
// H=str.replace(Str, Regexp, Replacement) :-
// 	str(Str), str(Regexp), str(Replacement) | H=[:/*inline*/
// 	Str s=null;
// 	try {
// 		s = me.nth(0).replaceAll(
// 		((StrFunctor)me.nthAtom(1).getFunctor()).strValue(),
// 		((StrFunctor)me.nthAtom(2).getFunctor()).strValue()
// 		);
// 	} catch(Exception e) {}
// 	if(s==null) s = ((StrFunctor)me.nthAtom(0).getFunctor()).strValue();
// 	Atom result = mem.newAtom(new StrFunctor(s));
// 	mem.relink(result, 0, me, 3);
// 	me.nthAtom(0).remove();
// 	me.nthAtom(1).remove();
// 	me.nthAtom(2).remove();
// 	me.remove();
// 	:](Str, Regexp, Replacement).

// /**
//  * str.match(+Str, +Regexp, -Res):
//  * 
//  * 与えられた文字列に指定されたパターン文字列が部分的にマッチするかどうかをかえす。
//  * @param +Str 元の文字列
//  * @param +Regexp パターン文字列
//  * @param -Res 結果 (マッチする時 true/1 マッチしない時 false/1 (パターン文字列が変だったときは false) )
//  */
// //（Str.match は全体とマッチするかどうかなので微妙に違う。）
// H=str.match(Str, Regexp) :-
// 	str(Str), str(Regexp) | H=[:/*inline*/
// 	boolean b=false;
// 	try {
// 		b = java.util.regex.Pattern.compile(
// 		((StrFunctor)me.nthAtom(1).getFunctor()).strValue() ).matcher(
// 		((StrFunctor)me.nthAtom(0).getFunctor()).strValue() ).find();
// 	} catch(Exception e) {e.printStackTrace();}
// 	Atom result = mem.newAtom(new SymbolFunctor(b?"true":"false", 1));
// 	mem.relink(result, 0, me, 2);
// 	me.nthAtom(0).remove();
// 	me.nthAtom(1).remove();
// 	me.remove();
// 	:](Str, Regexp).

// /**
//  * str.split(+Regexp, +Str, -Res):
//  *
//  * 指定されたパターン文字列で区切られた文字列のリストを返す。
//  * @param +Regexp パターン文字列
//  * @param +Str 元の文字列
//  * @param -Res 結果(文字列のリスト)
//  * @example H=split([:\s+:], [:1 2 3:])  ==>  H='.'("1", '.'("2", '.'("3", '[]')))
//  */
// H=str.split(Regexp, S) :- str(Regexp), str(S) | H=[:/*inline*/
// 	Str r[] = ((StrFunctor)me.nthAtom(1).getFunctor()).strValue().split(
// 	((StrFunctor)me.nthAtom(0).getFunctor()).strValue() );

// //	util.Util.makeList(me.getArg(2), java.util.Arrays.asList(r));

// // util.Util.makeListのcopy&paste&修正
// 	List l = java.util.Arrays.asList(r);
// 	Link link = me.getArg(2);

// 	Iterator it = l.iterator();
// 	//AbstractMembrane mem = link.getAtom().getMem();
// 	Atom parent=null;
// 	boolean first=true;
// 	while(it.hasNext()) {
// 		Atom c = mem.newAtom(new SymbolFunctor(".", 3));  // .(Value Next Parent)
// 		Atom v = mem.newAtom(new StrFunctor(it.next().toStr()));
// 		//new SymbolFunctor(it.next().toStr(), 1)); // value(Value)
// 		mem.newLink(c, 0, v, 0);
// 		if(first) {
// 			mem.inheritLink(c, 2, link);
// 		} else {
// 			mem.newLink(c, 2, parent, 1);
// 		}
// 		parent = c;
// 		first=false;
// 	}
// 	Atom nil = mem.newAtom(new SymbolFunctor("[]", 1));
// 	if(first) {
// 		mem.inheritLink(nil, 0, link);
// 	} else {
// 		mem.newLink(nil, 0, parent, 1);
// 	}
	
// 	mem.removeAtom(me.nthAtom(0));
// 	mem.removeAtom(me.nthAtom(1));
// 	mem.removeAtom(me);
// 	:](Regexp, S).

// /**
//  * str.join(+Glue, +StrList, -Res):
//  *
//  * 与えられた文字列のリストを指定された結合子で結合した文字列を返す。 
//  * 空リストを渡すと空文字列が返る (2006.07.24 inui)
//  * @param +Glue 結合子
//  * @param +StrList 文字列のリスト
//  * @param -Res 結果(文字列)
//  * @example H=join("_", ["1","2","3"])  ==>  H="1_2_3"
//  */
// H=str.concat(Glue0,str.join(Glue1, [])) :- str(Glue0), str(Glue1) | H="".
// H=str.join(Glue, []) :- str(Glue) | H="".	//2006.07.24 inui
// H=str.join(Glue, [CAR|CDR]) :- str(Glue) |
// 	H=str.concat(CAR, str.concat(Glue, str.join(Glue, CDR))).

/**
 * str.concat(+Str1, +Str2, -Res):
 * 
 * 文字列を結合する。
 * @param +Str1,+Str2 文字列
 * @example H='^'("abc", "de")  ==>  H="abcde"
 */
H=str.concat(S1, S2) :- string(S1), string(S2) |
    '$callback'('string_concat', S1, S2, H).

/**
 * str.substr(+Str, +Begin, -Res):
 * 
 * 文字列の指定された開始位置から始まり終端までの部分文字列を返す
 * @param +Str 元の文字列
 * @param +Begin 開始位置
 * @param -Res 結果(エラー時は空文字列)
 * @example H=str.substr("abc", 1) ==> H="bc"
 */
H=str.substr(S,Begin) :- string(S), int(Begin) |
    '$callback'('string_substr_right', S, Begin, H).

/**
 * str.substr(+Str, +Begin, +End, -Res):
 * 
 * 文字列の指定された開始位置から終了位置までの部分文字列を返す。
 * @param +Str 元の文字列
 * @param +Begin 開始位置
 * @param +End 終了位置
 * @param -Res 結果(エラー時は空文字列)
 * @example H=str.substr("abc", 1, 2) ==> H="b"
 */
H=str.substr(S,Begin,End) :- string(S), int(Begin), int(End) |
    '$callback'('string_substr', S, Begin, End, H).

// /**
//  * str.str_of_float(+Float, -Res):
//  * 
//  * @param +Float 浮動小数点数
//  * @param -Res 結果(エラー時は空文字列)
//  * @example H=str.str_of_float(3.5) ==> H="3.5"
//  */
// H=str.str_of_float(I) :- float(I) | H=[:/*inline*/
// 	Str s = null;
// 	try{
// 		s = Double.toStr(((FloatingFunctor)me.nthAtom(0).getFunctor()).floatValue());
// 	} catch(Exception e) {}
// 	Atom res = mem.newAtom(new StrFunctor((s==null)?"":s));
// 	mem.relinkAtomArgs(res, 0, me, 1);
// 	mem.removeAtom(me.nthAtom(0));
// 	mem.removeAtom(me);
// 	:](I).

/**
 * str.length(+Str, -Length):
 * 文字列を受け取って長さを返します
 * @example H=str.length("hello")  ==>  H=5
 */
//2007.07.02 inui
H=str.length(Str) :- string(Str) | '$callback'('string_length', Str, H).
	
/**
 * str.reverse(+Str, -ReversedStr):
 * 文字列を受け取って反転させた文字列を返します
 * @example H=str.length("hello")  ==>  H="olleh"
 */
//2007.07.02 inui
H=str.reverse(Str) :- string(Str) | '$callback'('string_reverse', Str, H).
}.
