From: cee1 <fy...@gm...> - 2009-12-13 13:18:05
|
Hi all, I'm reading the code of adam.cpp, and get totally lost. In the function sheet_t::implementation_t::get: (adam.cpp 1387) "if (initialize_mode_m) { ..." I've found initialize_mode_m is false when instantiates sheet_t::implementation_t, and will be true when calls add_constant, add_input or add_interface. So the following assert should always fail: (adam.cpp 1428) assert(cell.interface_input_m && ...), Because when this line is reached, the initialize_mode_m is false, then we should not have called add_constant, add_input or add_interface, so the cell is not an interface cell, assert failed. Also, I find some code that makes no sense to me, like: (adam.cpp 1267) sheet_t::implementation_t::initialize_one accumulate_contributing_m.reset(); ... cell.init_contributing_m |= accumulate_contributing_m; or (adam.cpp 1173) in function sheet_t::implementation_t::update if (cell.specifier_m == access_interface_output) get_stack_m.push_back(std::make_pair(cell.name_m, false)); ... if (cell.specifier_m == access_interface_output) get_stack_m.pop_back(); Sorry for this mass mail, but I feel lost in adam.cpp. Could someone show me the global picture of how these functions in sheet_t::implementation work? Regards, - cee1 |
From: Sean P. <sea...@ma...> - 2009-12-13 22:14:52
|
Hi cee1, Welcome! Questions on ASL are always appreciated. I'm not sure which version of the code you're referring too, the line numbers don't match up with the current release. I'm going to use the latest code from my sanbox here: http://stlab.adobe.com:8080/@lno=y@//sandbox/sparent/adobe_source_libraries/source/adam.cpp?ac=64&rev1=28 On Dec 13, 2009, at 5:17 AM, cee1 wrote: > Hi all, > I'm reading the code of adam.cpp, and get totally lost. It is a bit twisty - I've been slowing working on a rewrite using Boost Graph Library - but no ETA on when that will appear. > In the function sheet_t::implementation_t::get: > (adam.cpp 1387) "if (initialize_mode_m) { ..." > I've found initialize_mode_m is false when instantiates > sheet_t::implementation_t, and will be true when calls add_constant, > add_input or add_interface. So the following assert should always > fail: (line 1435 in my copy) When a sheet is constructed, initializers are evaluated as the cells are added. the get() function is called by the expression evaluator to look up variables. The expressions on a sheet initializer can only refer to cells that have been previously declared (added to the sheet) and the initializers don't attempt to follow relationships, they only pick up the cell value of previously initialized cells. > (adam.cpp 1428) assert(cell.interface_input_m && ...), > Because when this line is reached, the initialize_mode_m is false, > then we should not have called add_constant, add_input or > add_interface, so the cell is not an interface cell, assert failed. (line 1476) - there is a return statement on line 1449 so this line is not going to be reached if initialize_mode_m is true. > > Also, I find some code that makes no sense to me, like: > (adam.cpp 1267) sheet_t::implementation_t::initialize_one > accumulate_contributing_m.reset(); > ... > cell.init_contributing_m |= accumulate_contributing_m; (1315) accumulate_contributing_m is a member variable that holds a bit field corresponding to cells. Executing calculate_m() on line 1323 is going to set the bits for the cells that are read as part of that expression in accumulate_contributing_m. Then on line 1325 that bit set is or'ed with the other bits contributing to the initializer on that cell. > > or > > (adam.cpp 1173) in function sheet_t::implementation_t::update > if (cell.specifier_m == access_interface_output) > get_stack_m.push_back(std::make_pair(cell.name_m, false)); (1221) The get_stack_m is used to detect self-referential expressions in get() (which is called as part of calculating an expression for variable lookup). For example, if you have a rule like: a <== max(a, b); Then the lookup of "a" is self referential, and must refer to the initial value of "a", but "b" is not self referential and will refer to the final value of "b". See line 1475 for where this is used. > ... > if (cell.specifier_m == access_interface_output) > get_stack_m.pop_back(); > > > Sorry for this mass mail, but I feel lost in adam.cpp. Could someone > show me the global picture of how these functions in > sheet_t::implementation work? No problem - keep the questions coming. Sean > > > Regards, > - cee1 > ------------------------------------------------------------------------------ > Return on Information: > Google Enterprise Search pays you back > Get the facts. > http://p.sf.net/sfu/google-dev2dev > _______________________________________________ > Adobe-source-devel mailing list > Ado...@li... > https://lists.sourceforge.net/lists/listinfo/adobe-source-devel |
From: cee1 <fy...@gm...> - 2009-12-14 14:04:00
|
Hi Sean, Thanks for the replay. I'm reading code of ASL 1.0.42. > In the function sheet_t::implementation_t::get: > (adam.cpp 1387) "if (initialize_mode_m) { ..." > I've found initialize_mode_m is false when instantiates > sheet_t::implementation_t, and will be true when calls add_constant, > add_input or add_interface. So the following assert should always fail: > > > (line 1435 in my copy) When a sheet is constructed, initializers are > evaluated as the cells are added. the get() function is called by the > expression evaluator to look up variables. The expressions on a sheet > initializer can only refer to cells that have been previously declared > (added to the sheet) and the initializers don't attempt to follow > relationships, they only pick up the cell value of previously initialized > cells. > > Is "sheet_t::implementation_t::get" (only) directly used in the following line? (i.e. when an interface cell has no define expression): 799. cell_set_m.push_back(cell_t(access_interface_output, name, 800. boost::bind(&implementation_t::get, boost::ref(*this), name), 801. cell_set_m.size(), &cell_set_m.back())); > (adam.cpp 1428) assert(cell.interface_input_m && ...), > Because when this line is reached, the initialize_mode_m is false, then we > should not have called add_constant, add_input or add_interface, so the cell > is not an interface cell, assert failed. > > > (line 1476) - there is a return statement on line 1449 so this line is not > going to be reached if initialize_mode_m is true. > > I found initialize_mode_m is true when: a) reinitialize is called b) add_constant is called c) add_input is called d) add_interface is called No place except constructor of sheet_t::implementation_t set initialize_mode_m false. The line 1476: assert(cell.interface_input_m && "FATAL (sparent) : Only interface cells should be on the get stack."); That means we expect an interface cell here, but if we have an interface cell, it should be added by add_interface, then initialize_mode_m should be true: this line is not reachable ? > > Also, I find some code that makes no sense to me, like: > (adam.cpp 1267) sheet_t::implementation_t::initialize_one > accumulate_contributing_m.reset(); > ... > cell.init_contributing_m |= accumulate_contributing_m; > > > (1315) accumulate_contributing_m is a member variable that holds a bit > field corresponding to cells. Executing calculate_m() on line 1323 is going > to set the bits for the cells that are read as part of that expression in > accumulate_contributing_m. Then on line 1325 that bit set is or'ed with the > other bits contributing to the initializer on that cell. > > In many places, calculate_m is a binding function object which is essentially implementation_t::calculate_expression -- this function doesn't touch accumulate_contributing_m. But calculate_m can also be a binding function object which is essentially implementation_t::get -- this function touches accumulate_contributing_m. Am I right? > > or > > (adam.cpp 1173) in function sheet_t::implementation_t::update > if (cell.specifier_m == access_interface_output) > get_stack_m.push_back(std::make_pair(cell.name_m, false)); > > > (1221) The get_stack_m is used to detect self-referential expressions in > get() (which is called as part of calculating an expression for variable > lookup). For example, if you have a rule like: > > a <== max(a, b); > > Then the lookup of "a" is self referential, and must refer to the initial > value of "a", but "b" is not self referential and will refer to the final > value of "b". > > See line 1475 for where this is used. > > ... > if (cell.specifier_m == access_interface_output) get_stack_m.pop_back(); > > Does that means sheet_t::implementation_t::get may be called recursively? > > > Sorry for this mass mail, but I feel lost in adam.cpp. Could someone show > me the global picture of how these functions in sheet_t::implementation > work? > > > No problem - keep the questions coming. > Thank you. Regards, - cee1 |
From: Sean P. <sea...@ma...> - 2009-12-14 16:32:06
|
On Dec 14, 2009, at 6:03 AM, cee1 wrote: > Hi Sean, > > Thanks for the replay. > I'm reading code of ASL 1.0.42. Okay - that should be here <http://stlab.adobe.com:8080/@lno=y@//source_release/source/adam.cpp?ac=64&rev1=11 > >> In the function sheet_t::implementation_t::get: >> (adam.cpp 1387) "if (initialize_mode_m) { ..." >> I've found initialize_mode_m is false when instantiates >> sheet_t::implementation_t, and will be true when calls >> add_constant, add_input or add_interface. So the following assert >> should always fail: > > (line 1435 in my copy) When a sheet is constructed, initializers are > evaluated as the cells are added. the get() function is called by > the expression evaluator to look up variables. The expressions on a > sheet initializer can only refer to cells that have been previously > declared (added to the sheet) and the initializers don't attempt to > follow relationships, they only pick up the cell value of previously > initialized cells. > > Is "sheet_t::implementation_t::get" (only) directly used in the > following line? (i.e. when an interface cell has no define > expression): > 799. cell_set_m.push_back(cell_t(access_interface_output, > name, > 800. > boost::bind(&implementation_t::get, boost::ref(*this), name), > 801. cell_set_m.size(), > &cell_set_m.back())); When there is no define expression it is equivalent to a <== a. This call binds ::get() to the cell to implement that expression. implementation_t::get can also be called from sheet_t::get. It is part of the public interface to a sheet. 611. any_regular_t sheet_t::get(name_t cell) 612. { return object_m->get(cell); } > >> (adam.cpp 1428) assert(cell.interface_input_m && ...), >> Because when this line is reached, the initialize_mode_m is false, >> then we should not have called add_constant, add_input or >> add_interface, so the cell is not an interface cell, assert failed. > > (line 1476) - there is a return statement on line 1449 so this line > is not going to be reached if initialize_mode_m is true. > > I found initialize_mode_m is true when: > a) reinitialize is called > b) add_constant is called > c) add_input is called > d) add_interface is called > No place except constructor of sheet_t::implementation_t set > initialize_mode_m false. Yes, it is true for the duration of the scope variable in those calls and then restored to it's prior value. > > The line 1476: assert(cell.interface_input_m && "FATAL (sparent) : > Only interface cells should be on the get stack."); > That means we expect an interface cell here, but if we have an > interface cell, it should be added by add_interface, then > initialize_mode_m should be true: this line is not reachable ? >> >> Also, I find some code that makes no sense to me, like: >> (adam.cpp 1267) sheet_t::implementation_t::initialize_one >> accumulate_contributing_m.reset(); >> ... >> cell.init_contributing_m |= accumulate_contributing_m; > > (1315) accumulate_contributing_m is a member variable that holds a > bit field corresponding to cells. Executing calculate_m() on line > 1323 is going to set the bits for the cells that are read as part of > that expression in accumulate_contributing_m. Then on line 1325 that > bit set is or'ed with the other bits contributing to the initializer > on that cell. > > In many places, calculate_m is a binding function object which is > essentially implementation_t::calculate_expression -- this function > doesn't touch accumulate_contributing_m. > But calculate_m can also be a binding function object which is > essentially implementation_t::get -- this function touches > accumulate_contributing_m. > Am I right? calculate_expression calls the virtual machine to evaluate the expression, the virtual machine will call sheet_t::get() to do variable lookup, this will call implementation_t::get(). >> >> or >> >> (adam.cpp 1173) in function sheet_t::implementation_t::update >> if (cell.specifier_m == access_interface_output) >> get_stack_m.push_back(std::make_pair(cell.name_m, false)); > > (1221) The get_stack_m is used to detect self-referential > expressions in get() (which is called as part of calculating an > expression for variable lookup). For example, if you have a rule like: > > a <== max(a, b); > > Then the lookup of "a" is self referential, and must refer to the > initial value of "a", but "b" is not self referential and will refer > to the final value of "b". > > See line 1475 for where this is used. > >> ... >> if (cell.specifier_m == access_interface_output) >> get_stack_m.pop_back(); > > Does that means sheet_t::implementation_t::get may be called > recursively? Yes. Getting the value of a cell may cause that's cell expression to be evaluated (see calls to cell.calculate()), this will invoke the virtual machine and may call back sheet_t::get() to do a variable lookup. >> >> >> Sorry for this mass mail, but I feel lost in adam.cpp. Could >> someone show me the global picture of how these functions in >> sheet_t::implementation work? > > No problem - keep the questions coming. > > Thank you. > > > Regards, > - cee1 |