$Id: VXMLDoc-README.txt,v 1.1 2008/10/05 01:33:42 nishimoto Exp $

(c)2003 Takuya NISHIMOTO (nishi@hil.t.u-tokyo.ac.jp)

phoenix/document/00README

本ドキュメントは、VXMLDoc.java が VoiceXML ファイルを
内部コマンドに変換する場合の詳細を記述したものです。

===========================================
TODO (by nishi)
===========================================

- ドキュメントのスコープ管理と property タグの実装

===========================================
private void _makeDialogCommonStates()
===========================================

 <state id="@dialog.@restart">
  <cmd>
   <stopoutput />
   <end now="false">'gdm_start.pdoc'</end>
  </cmd>
 </state>
 
 <state id="@dialog.@pause">
  <cmd>
   <stopoutput />
   <add><log with="dialog">'PAUSE'</log></add>
   <add><break>10000</break></add>
   <next>'@dialog.@pause'</next>
  </cmd>
  <catch text="GDM_RESUME">
   <goto>'@dialog.@resume'</goto>
  </catch>
 </state>
 
 <state id="@dialog.@resume">
  <cmd>
   <stopoutput />
   <add><log with="dialog">'RESUME'</log></add>
   <next>'@dialog.@select'</next>
  </cmd>
 </state>

===========================================
Application Root Document の初期化
===========================================

  document = new Object(); 
  dialog = new Object(); 
  var $root = '/path/to/drivenavi_root.vxml';
  if ( $current_root == undefined ) {
     var $current_root;
  }
  if ( $current_root != $root ) {
     $current_root = $root;
     session = new Object();
     application = new Object(); 
    
     application.spot_genre=null;
     application.time_required=null; 
     application.genre_detail=null;
     application.price=null; 
     application.debug=false; 
  }

===========================================
プロンプト選択アルゴリズムの例
===========================================

*** source ***

<form id="main">
 <field name="place">
  <prompt> 場所をどうぞ。</prompt>
  <prompt count="3"> 東京と京都のどちらですか？</prompt>
  <grammar>
   <rule><token phoneme="t;o:;ky;o:;">東京</token></rule>
   <rule><token phoneme="ky;o:;t;o;">京都</token></rule>
  </grammar>
 </field>
 <block> <goto next="#confirm"/> </block>
</form>

*** target ***

<state id="@main.place">
 <cmd>
  <next>'@main.place'</next>

  <cmd cond="!main.place$.noprompt">
   // 初期化しながら cond == false を削除
   <script with="main.place$">
     p1 = true;    
     p2 = true;    
   </script>
   // cc := 現在のカウント値以下で，各要素の count 属性の最大値
   // cc=correct count
   <script with="main.place$">
     cc = 1;	    
     // p1: count=null then "1"
     // p2: count="3"
     if ( 1 <= promptcount && cc < 1 ) {cc = 1}
     if ( 3 <= promptcount && cc < 3 ) {cc = 3}
   </script>
   // cc と同じ count 値を持たない要素をリストから削除
   // ただし cond で削除されたものはあらかじめ false
   <script with="confirm.select$">
     if ( 1 != cc ) { p1=false }
     if ( 3 != cc ) { p2=false }
   </script>

   <!-- バージイン対策 ここでincする -->
   <script>main.place$.promptcount++;</script>
   <!-- execute prompt list -->
   <cmd cond="main.place$.p1">
    <add><voice with="main">'場所をどうぞ。'</voice></add>
   </cmd>
   <cmd cond="main.place$.p2">
    <add><voice with="main">'東京と京都のどちらですか？'</voice></add>
   </cmd>

  </cmd> // cond="!main.place$.noprompt"

  <add><break length="10.0"/></add>
 </cmd>

 <catch next="@main.place.$1">東京</catch>
 <catch next="@main.place.$2">京都</catch>
</state>

*** source ***

<menu id="confirm">
 <prompt>よろしいですか？</prompt>
 <prompt count="2">はい，または，いいえ，でお答えください．</prompt>
 <prompt count="4">いったいどっちですか？</prompt>
 <choice next="#yes">
  <grammar><rule> <token phoneme="h;a;i;">はい</token> </rule></grammar>
 </choice>
 <choice next="#no">
  <grammar><rule> <token phoneme="i:;e;">いいえ</token> </rule></grammar>
 </choice>
</menu>

*** target ***

<state id="@confirm._menu_">
<--
[p1]<prompt>よろしいですか？</prompt>
[p2]<prompt cond="hoge==true">ほげ？</prompt>
[p3]<prompt count="2">はい，または，いいえ，でお答えください．</prompt>
[p4]<prompt count="4">いったいどっちですか？</prompt>
-->
 <cmd>
  <cmd>
   // 初期化しながら cond == false を削除
   <script with="confirm.select$">
     p1 = true;    
     p2 = (hoge==true);
     p3 = true;    
     p4 = true;    
   </script>

   // cc := 現在のカウント値以下で，各要素の count 属性の最大値
   // cc=correct count
   <script with="confirm._menu_$">
     cc = 1;	    
     // p1: count=null then "1"
     // p2: count=null then "1"
     // p3: count="2"
     // p4: count="4"
     if ( 1 <= promptcount && cc < 1 ) {cc = 1}
     if ( 1 <= promptcount && cc < 1 ) {cc = 1}
     if ( 2 <= promptcount && cc < 2 ) {cc = 2}
     if ( 4 <= promptcount && cc < 4 ) {cc = 4}
     // 検証:
     //  if promptcount=1, cc=1 : 実行なし  : cc = 1 (p1,p2)
     //  if promptcount=2, cc=1 : 3行目実行 : cc = 2 (p3)
     //  if promptcount=3, cc=2 : 実行なし  : cc = 2 (p3)
     //  if promptcount=4, cc=2 : 4行目実行 : cc = 4 (p4)
     //  if promptcount=5, cc=4 : 実行なし  : cc = 4 (p4)
   </script>

   // cc と同じ count 値を持たない要素をリストから削除
   // ただし cond で削除されたものはあらかじめ false
   <script with="confirm._menu_$">
     if ( 1 != cc ) { p1=false }
     if ( 1 != cc ) { p2=false }
     if ( 2 != cc ) { p3=false }
     if ( 4 != cc ) { p4=false }
   </script>
  </cmd>

  <!-- inc promptcount -->
  <script>confirm._menu_$.promptcount++;</script>

  <!-- execute prompt list -->
  <cmd cond="confirm._menu_$.p1">
   <add><voice with="confirm">'よろしいですか？'</voice></add>
   <add><break length="10.0"/></add>
  </cmd>
  <cmd cond="confirm._menu_$.p2">
   <add><voice with="confirm">'はい，または，いいえ，でお答えください．'</voice></add>
   <add><break length="10.0"/></add>
  </cmd>
  <cmd cond="confirm._menu_$.p2">
   <add><voice with="confirm">'いったいどっちですか？'</voice></add>
   <add><break length="10.0"/></add>
  </cmd>

 </cmd>
 <catch next="@yes">はい</catch>
 <catch next="@no">いいえ</catch>
</state>

[end of file]
