• R/O
  • SSH
  • HTTPS

adp: Commit


Commit MetaInfo

Revision299 (tree)
Time2012-06-07 23:53:24
Authorohfuji

Log Message

パフォーマンスを維持しつつCutも早くした。

Change Summary

Incremental Difference

--- trunk/adp_builtin_system.h (revision 298)
+++ trunk/adp_builtin_system.h (revision 299)
@@ -266,7 +266,7 @@
266266
267267 bc = get_gc();
268268 set_gc(c); // グローバルコンテクストをセット
269- ec = new ExecContext( c->topgoals.upHorn(0)->getGoal(), c->topgoals.upHorn(0)->getVcnt());
269+ ec = new ExecContext( c->topgoals.upHorn(0)->getGoal(), c->topgoals.upHorn(0)->getVcnt(), c->topgoals.upHorn(0)->vstat);
270270 bool ret = ec->execute(excp, true);
271271
272272 set_gc(bc); // グローバルコンテクストを元に戻す
--- trunk/adp_base.h (revision 298)
+++ trunk/adp_base.h (revision 299)
@@ -121,6 +121,7 @@
121121 typedef Array<const PObject*> PObjectArray;
122122 typedef ArrayNoexpand<const PObject*> PObjectArrayNE;
123123 typedef ArrayNoexpand<const PObject*> VLocal;
124+typedef Array<unsigned char> ByteArray;
124125 typedef map<string, size_t> HashArrayMap;
125126 typedef pair<string, size_t> HashArrayPair;
126127
--- trunk/adp_unify.cpp (revision 298)
+++ trunk/adp_unify.cpp (revision 299)
@@ -166,7 +166,9 @@
166166 } else {
167167 const PObject *p = gval->getval2(c, c->gl); // getvalに置き換え可能(getval_gl,getval_hlを作成後置き換える
168168 (*hlocal)[horn.idx] = p;
169- if ( p->isc() ) return true;
169+ if ( p->isc() ) {
170+ return true;
171+ }
170172 }
171173 } else if ( hval != 0 ) {
172174 const PObject *p = hval->getval2(c, c->hl);
@@ -584,6 +586,13 @@
584586 return lo ? lo : this;
585587 }
586588
589+void PList::mark_hlocal(ExecContext *c, Array<bool> &marker) const
590+{
591+ if ( constant ) return;
592+ lvalue->mark_hlocal(c, marker);
593+ rvalue->mark_hlocal(c, marker);
594+}
595+
587596 const PObject *PArray::getval( ExecContextRoot *c) const
588597 {
589598 if ( constant ) return this;
@@ -603,7 +612,6 @@
603612 return po ? po : this;
604613 }
605614
606-
607615 const PObject *PArray::getval2( ExecContextRoot *c, VLocal *vlocal) const
608616 {
609617 if ( constant ) return this;
@@ -622,6 +630,16 @@
622630 return po ? po : this;
623631 }
624632
633+void PArray::mark_hlocal(ExecContext *c, Array<bool> &marker) const
634+{
635+ if ( constant ) return;
636+
637+ for ( PObjectArray::const_iterator i = value.begin(); i < value.end(); i++ ) {
638+ (*i)->mark_hlocal(c, marker);
639+ }
640+}
641+
642+
625643 const PObject *PPredicate::getval( ExecContextRoot *c) const
626644 {
627645 if ( constant ) return this;
@@ -652,6 +670,12 @@
652670 return this;
653671 }
654672
673+void PPredicate::mark_hlocal(ExecContext *c, Array<bool> &marker) const
674+{
675+ name->mark_hlocal(c, marker);
676+ arglist.mark_hlocal(c, marker);
677+}
678+
655679 const PObject *PVeriable::getval( ExecContextRoot *c) const
656680 {
657681 assert( idx < c->gl->size());
@@ -676,9 +700,22 @@
676700 }
677701 }
678702
703+void PVeriable::mark_hlocal(ExecContext *c, Array<bool> &marker) const
704+{
705+ marker[idx] = true;
706+}
707+
708+
679709 const PObject *PEVeriable::getval( ExecContextRoot *c) const { return GetValsOne<const PObject *>( *this, c, vl, &PObject::getval, this); }
680710 const PObject *PEVeriable::getval2( ExecContextRoot *c, VLocal *) const { return GetValsTwo<const PObject *>( *this, c, vl, vl, &PObject::getval2, this); }
681711
712+void PEVeriable::mark_hlocal(ExecContext *c, Array<bool> &marker) const
713+{
714+ if ( vl == c->hl ) {
715+ marker[idx] = true;
716+ }
717+}
718+
682719 /*************************************** c_integer?? ******************************************/
683720 const PINTEGER32 *PVeriable::p_integer32(ExecContextRoot *c) const { return GetValsOne<const PINTEGER32*>( *this, c, c->gl, &PObject::p_integer32, 0); }
684721 const PINTEGER *PVeriable::p_integer(ExecContextRoot *c) const { return GetValsOne<const PINTEGER*>( *this, c, c->gl, &PObject::p_integer, 0); }
--- trunk/adp_compile.h (revision 298)
+++ trunk/adp_compile.h (revision 299)
@@ -199,6 +199,10 @@
199199 virtual const PObject *getval( ExecContextRoot *) const { return this; }
200200 virtual const PObject *getval2( ExecContextRoot *, VLocal *) const { return this; }
201201
202+ // 変数の追跡(cutで使用)
203+ virtual void mark_hlocal( ExecContext *, Array<bool> &marker) const {};
204+
205+
202206 // 値の取得
203207 virtual const char *c_str() const { return 0; };
204208 virtual const double *c_double() const { return 0; };
@@ -908,6 +912,8 @@
908912 virtual const PObject *getval( ExecContextRoot *) const;
909913 virtual const PObject *getval2( ExecContextRoot *c, VLocal *vlocal) const;
910914
915+ // 変数の追跡(cutで使用)
916+ virtual void mark_hlocal( ExecContext *c, Array<bool> &marker) const;
911917
912918 // 変換して値を取得
913919 virtual bool cnv_string(string &value) const {
@@ -1227,6 +1233,9 @@
12271233 virtual const PObject *getval( ExecContextRoot *c) const;
12281234 virtual const PObject *getval2( ExecContextRoot *c, VLocal *vlocal) const;
12291235
1236+ // 変数の追跡(cutで使用)
1237+ virtual void mark_hlocal( ExecContext *c, Array<bool> &marker) const;
1238+
12301239 // 変換して値を取得
12311240 virtual bool cnv_string(string &value) const {
12321241 value += (!brace ? '(' : '{');
@@ -1473,6 +1482,9 @@
14731482 virtual const PObject *getval( ExecContextRoot *c) const;
14741483 virtual const PObject *getval2( ExecContextRoot *c, VLocal *vlocal) const;
14751484
1485+ // 変数の追跡(cutで使用)
1486+ virtual void mark_hlocal( ExecContext *c, Array<bool> &marker) const;
1487+
14761488 // メモリマネージャによるdelete
14771489 virtual void del();
14781490 virtual void deltree(PObjectArray *objs); // objsに関係しているメモリを削除(持っているオブジェクトも合わせて削除する)
@@ -1591,6 +1603,10 @@
15911603 // 値の取得
15921604 virtual const PObject *getval( ExecContextRoot *c) const ;
15931605 virtual const PObject *getval2( ExecContextRoot *c, VLocal *vlocal) const ;
1606+
1607+ // 変数の追跡(cutで使用)
1608+ virtual void mark_hlocal( ExecContext *c, Array<bool> &marker) const;
1609+
15941610 // 値の取得
15951611 virtual const PINTEGER32 *p_integer32(ExecContextRoot *c) const ;
15961612 virtual const PINTEGER *p_integer(ExecContextRoot *c) const ;
@@ -1803,6 +1819,10 @@
18031819 // 値の取得
18041820 virtual const PObject *getval( ExecContextRoot *c) const;
18051821 virtual const PObject *getval2( ExecContextRoot *c, VLocal *) const;
1822+
1823+ // 変数の追跡(cutで使用)
1824+ virtual void mark_hlocal( ExecContext *c, Array<bool> &marker) const;
1825+
18061826 // 値の取得
18071827 virtual const PINTEGER32 *p_integer32(ExecContextRoot *c) const ;
18081828 virtual const PINTEGER *p_integer(ExecContextRoot *c) const ;
@@ -1888,10 +1908,11 @@
18881908 PGoal body;
18891909 size_t vcnt;
18901910 VNames vnames;
1911+ ByteArray vstat;
18911912 bool constant;
18921913
18931914 PHorn() : head(), body(), vcnt(0), vnames(), constant(false) {}
1894- explicit PHorn( const PHorn &rhs) : head(rhs.head), body(rhs.body), vcnt(rhs.vcnt), vnames(rhs.vcnt), constant(rhs.constant) {}
1915+ explicit PHorn( const PHorn &rhs) : head(rhs.head), body(rhs.body), vcnt(rhs.vcnt), vstat(), vnames(rhs.vcnt), constant(rhs.constant) {}
18951916
18961917 virtual bool isMyObject(char keychar) const {return keychar == '+' ? true : false;}
18971918 virtual PObject *compile(CompileContext &c);
@@ -1934,10 +1955,11 @@
19341955 PGoal &getGoal() { return body; }
19351956 size_t getVcnt() { return vcnt; }
19361957 VNames &getVnames() { return vnames; }
1937- void setGoal( PGoal &goal_, VNames &vnames_ ) {
1958+ void setGoal( PGoal &goal_, VNames &vnames_, ByteArray &vstat_ ) {
19381959 body = goal_;
19391960 vcnt = vnames_.size();
19401961 vnames = vnames_;
1962+ vstat = vstat_;
19411963 constant = goal_.isc();
19421964 }
19431965 bool upHorn( const PPredicate &goal, ExecContext &c, bool skipnamechk);
@@ -2000,7 +2022,7 @@
20002022 virtual ~PHorns() {}
20012023
20022024 void addHorn(PHorn *horn_);
2003- void addGoal(PGoal &goal_, VNames &vnames_);
2025+ void addGoal(PGoal &goal_, VNames &vnames_, ByteArray &vstat_);
20042026 void erase( size_t i);
20052027 void addPHorns(PHorns &horns_);
20062028 size_t size() { return horns.size(); }
@@ -2750,8 +2772,10 @@
27502772 bool eofflg;
27512773
27522774 public:
2753- VNames vary;
2754- bool result;
2775+ VNames vary; // 変数
2776+ ByteArray vstat; /* ローカル変数のステータス 0:カット後は使用しない(ただし引数は除く)、3:カット後も使用する変数。 */
2777+ Array<PPredicate*> cut; /* カット述語:のちにvstatの結果を引数に入れる(3のものを入れる) */
2778+ bool result; /* コンパイル結果 result == true コンパイルOK */
27552779 vector<string> ewmsg;
27562780 PGoal *goalcontext; // 現在コンパイル中のゴール節:式を処理する為に必要
27572781
--- trunk/adp_execute.h (revision 298)
+++ trunk/adp_execute.h (revision 299)
@@ -532,7 +532,7 @@
532532 struct ExecContext_Pipe;
533533
534534 struct ExecContext : public ExecContextBase {
535- VLocal hlocal; /* ホーン節側ローカル */
535+ VLocal hlocal; /* ホーン節側ローカル変数エリア */
536536
537537 ArrayNoexpand<size_t> afterunify; /* 評価後に再度ユニフィケーションを行う引数のIDX */
538538
@@ -574,7 +574,7 @@
574574 last_result = false;
575575 };
576576
577- ExecContext(PGoal &goal_, size_t vcnt_) : ExecContextBase(),
577+ ExecContext(PGoal &goal_, size_t vcnt_, ByteArray &vstat_) : ExecContextBase(),
578578 hlocal(), afterunify(), vcnt(vcnt_), g(0), ecs() {
579579 horn = 0;
580580 goal = &goal_;
@@ -697,10 +697,36 @@
697697 struct ExecContext_Cut : public ExecContextRoot {
698698 ExecContext_Cut(ExecContext *p_, void *f_, const PPredicate *pred_, VLocal *l) : ExecContextRoot(p_, f_, pred_, l) { delflg = false; }
699699 virtual bool first(PException &excp) {
700- // 親のローカル変数の値をcloneする、
700+ // 使用予定の親のローカル変数の値をcloneする、
701+ Array<bool> maker;
702+ maker.assign( p->hlocal.size(), false);
703+
704+ // 引数で指定された使用予定の変数をマークする
705+ for ( size_t i = 0; i < pred->size(); i++ ) {
706+ const PVeriable *v = dynamic_cast<const PVeriable*>((*pred)[i]);
707+ if ( v ) {
708+ maker[v->idx] = true;
709+ }
710+ }
711+
712+ // 戻り値で使用する変数をマークする
713+ if ( p->horn ) {
714+ size_t hsiz = p->horn->head.arglist.value.size();
715+ size_t gsiz = p->pred->arglist.value.size();
716+ for ( ArrayNoexpand<size_t>::iterator i = p->afterunify.begin(); i < p->afterunify.end(); i++ ) {
717+ p->horn->head.arglist.value[*i]->mark_hlocal( p, maker);
718+ }
719+ if ( gsiz < hsiz && p->afterunify.back() == gsiz - 1) {
720+ for ( size_t j = gsiz - 1; j < hsiz; j++ ) {
721+ p->horn->head.arglist.value[j]->mark_hlocal( p, maker);
722+ }
723+ }
724+ }
725+
726+ // マークした変数をコピーする
701727 for ( size_t i = 0; i < p->hlocal.size(); i++ ) {
702728 const PObject *o = p->hlocal[i];
703- if ( o != 0 /*&& !o->isc()*/ ) {
729+ if ( o != 0 && maker[i] == true ) {
704730 p->hlocal[i] = o->getval2(p,&p->hlocal)->clone(&p->objs);
705731 }
706732 }
--- trunk/adp_compile.cpp (revision 298)
+++ trunk/adp_compile.cpp (revision 299)
@@ -366,9 +366,11 @@
366366 VNames::iterator i;
367367 if ( (i = find(c.vary.begin(), c.vary.end(), name)) == c.vary.end() ) {
368368 c.vary.push_back(name);
369+ c.vstat.push_back(0);
369370 i = c.vary.end() - 1;
370371 }
371372 idx = i - c.vary.begin();
373+ if ( !c.cut.empty() ) c.vstat[idx] = 3; // after cut
372374 }
373375
374376
@@ -549,6 +551,11 @@
549551 p->value = c.fname;
550552 return p; // キーワードFILEになる。// このObjectのNewが余分(本来はこの呼出し元でDelete出来るハズ)
551553 }
554+ if ( ncmp("!") ) {
555+ // cut述語、後に引数に保存する変数を入れる
556+ c.cut.push_back(this);
557+ }
558+
552559 // 述語リスト
553560 c.skip();
554561 if ( *c == '(' ) {
@@ -784,7 +791,7 @@
784791 // 戻り値の追加(こっちはもらったものを単純についかする)
785792 void PPredicate::addMethodArg(CompileContext &c, PObject *l, PObject *dst)
786793 {
787- arglist.insert_front(l);
794+ if ( l ) arglist.insert_front(l);
788795 if ( dst ) {
789796 if ( opt.result_array ) {
790797 PVeriable *v = dynamic_cast<PVeriable*>(dst);
@@ -933,12 +940,29 @@
933940 // バックトラックの最適化
934941 if ( !body.empty() ) {
935942 const PPredicate *p = dynamic_cast<const PPredicate *>(body.back());
943+ // 最後のカットは取り除く(first/backtrackメソッドで頑張る)
936944 if ( p != 0 ) {
937945 if ( p->ncmp("!") ) {
938946 body.pop_back();
939947 nobacktrack = true;
948+ if ( c.cut.size() == 1 ) {
949+ c.cut.clear();
950+ }
940951 }
941952 }
953+ // 途中のカットに関しては引数に保存する変数を入れる
954+ for ( size_t i = 0; i < c.vstat.size(); i++ ) {
955+ if ( c.vstat[i] == 3 ) {
956+ PVeriable *v = get_gc()->factory.createObject<PVeriable>();
957+ v->makeVeriable(c, c.vary[i], false );
958+ // カットが複数ある場合、本来ならそのカットの位置に対して保存する変数を決定すべきだが
959+ // そんなにカットを使う機会も考えられないのでカット1つを想定して最適化している
960+ for ( size_t j = 0; j < c.cut.size(); j++ ) {
961+ c.cut[j]->addMethodArg(c,0,v);
962+ }
963+ }
964+ }
965+
942966 }
943967 return this;
944968 }
@@ -951,6 +975,8 @@
951975 }
952976 c.horn = true;
953977 c.vary.clear();
978+ c.vstat.clear();
979+ c.cut.clear();
954980 if ( isMyObject(*c) ) c.next_noskip(); // skip head char
955981 if ( *c == ',' || *c ==';' ) { // Horn headの繰り返し省略
956982 if ( c.p_head == 0 ) {
@@ -958,6 +984,7 @@
958984 } else {
959985 head = *c.p_head;
960986 c.vary = c.p_vary;
987+ c.vstat.assign( c.vary.size(), 0);
961988 }
962989 if ( *c == ',' ) c.next();
963990 } else {
@@ -996,6 +1023,7 @@
9961023 }
9971024 vcnt = c.vary.size();
9981025 vnames = c.vary;
1026+ vstat = c.vstat;
9991027 constant = (head.isc() && body.isc() );
10001028 c.horn = false;
10011029 return this;
@@ -1017,10 +1045,10 @@
10171045 horns.push_back(horn_);
10181046 }
10191047
1020-void PHorns::addGoal( PGoal &goal_, VNames &vnames_)
1048+void PHorns::addGoal( PGoal &goal_, VNames &vnames_, ByteArray &vstat_)
10211049 {
10221050 PHorn *p = get_gc()->factory.createObject<PHorn>();
1023- p->setGoal( goal_, vnames_);
1051+ p->setGoal( goal_, vnames_, vstat_);
10241052 horns.push_back(p);
10251053 if ( p->isc() == false ) constant = false;
10261054 }
--- trunk/adp_execute.cpp (revision 298)
+++ trunk/adp_execute.cpp (revision 299)
@@ -839,9 +839,11 @@
839839 PGoal goal;
840840 if ( goal.isMyObject(*c) || isalpha(*c) != 0 || *c == '_' || *c == '!' || *c == '=' || *c == '$' || *c == '%' ) {
841841 c.vary.clear();
842+ c.vstat.clear();
843+ c.cut.clear();
842844 goal.compile(c);
843845 if ( !goal.body.empty() ) {
844- topgoals.addGoal(goal, c.vary);
846+ topgoals.addGoal(goal, c.vary, c.vstat);
845847 }
846848 cflg = true;
847849 }
@@ -882,7 +884,7 @@
882884 PException excp;
883885 for ( goalidx = 0; goalidx < topgoals.size(); goalidx++ ) {
884886 PGoal &g = topgoals.upHorn(goalidx)->getGoal();
885- ExecContext ec( g, topgoals.upHorn(goalidx)->getVcnt());
887+ ExecContext ec( g, topgoals.upHorn(goalidx)->getVcnt(), topgoals.upHorn(goalidx)->vstat);
886888 try {
887889 excp.clear();
888890 ret = ec.execute(excp, true);
Show on old repository browser