On Fri, Feb 22, 2019 at 6:38 AM Arkady Klimov arkady.klimov_AT_gmail.com < refal@botik.ru> wrote:
> Антон, спасибо, > я тоже решил на этом коде немного поупражняться в чтении и понимании > Рефала-Плюс, что дается мне нелегко. Вроде все разобрал, но при этом мне > показалось, что тут есть ошибка (в смысле, что результат не лучший). А > именно, что будет в результате > <MSG_Expr ((EVAR) (TVAR) (EVAR)) (VVAR) > > ? > Я бы ожидал результат (VVAR), но тут вроде получится (EVAR). Корректно, > конечно, но обобщение не лучшее (не самое тесное). > Аркадий, да Вы правы. Основной смысл этой операции был в том, чтобы не склеивать выражения там, где не нужно (по выходу из блока). Обобщение (EVAR)...(EVAR) я либо оставил на потом и забыл, либо не стал делать из каких-то ещё соображений (но сейчас, даже подумав некоторое время, не смог сообразить, из каких). Антон P.S. Юра Климов восстановил доступ к сайту с исходниками. Например, обсуждаемый код здесь: http://trac.botik.ru/refal/browser/to-imperative/trunk/compiler/refal/org/refal/plus/compiler/rfp_format.rf Или я что-то не понимаю в этом коде? > Или такого входа быть не может? Например, если комбинации e t e заранее > заменяются на v? > Аркадий > > > >> >> *From:* Anton Orlov orlovan_AT_gmail.com <refal@botik.ru> >> *Sent:* Friday, February 22, 2019 9:43 AM >> *To:* refal@botik.ru >> *Cc**:* Александр Гусев <gusev_aleksa...@mail.ru> >> *Subject:* Re: Re[4]: Немного статистики >> >> >> >> Александр, >> >> >> >> Я, пожалуй, просто вставлю сюда код :) >> >> Он не самодостаточен, но алгоритм из него читаем. >> >> */** >> >> * * MSG-Exprs (e.Format1) e.Format2* >> >> * * Return e.Format3 -- most specific generalizing of formats 1 and 2.* >> >> * */* >> >> *MSG_Exprs* { >> >> ((*FAIL*)) *e*.Fe2 = *e*.Fe2; >> >> (*e*.Fe1) (*FAIL*) = *e*.Fe1; >> >> (*t*.Ft1 *e*.Fe1) *t*.Ft2 *e*.Fe2 \*?* >> >> */** >> >> * * IF both t.Ft1 and t.Ft2 are hard terms and aren't $const'ants then* >> >> * * split them out with MSG-Terms.* >> >> * */* >> >> { >> >> *t*.Ft1 : \{ (*EVAR*); (*VVAR*); (*CONST* *e*); } \*!* *$fail*; >> >> *t*.Ft2 : \{ (*EVAR*); (*VVAR*); (*CONST* *e*); } \*!* *$fail*; >> >> <*MSG_Terms* *t*.Ft1 *t*.Ft2> <*MSG_Exprs* (*e*.Fe1) *e*.Fe2>; >> >> }; >> >> (*e*.Fe1 *t*.Ft1) *e*.Fe2 *t*.Ft2 \*?* >> >> */** >> >> * * IF both t.Ft1 and t.Ft2 are hard terms and aren't $const'ants then* >> >> * * split them out with MSG-Terms.* >> >> * */* >> >> { >> >> *t*.Ft1 : \{ (*EVAR*); (*VVAR*); (*CONST* *e*); } \*!* *$fail*; >> >> *t*.Ft2 : \{ (*EVAR*); (*VVAR*); (*CONST* *e*); } \*!* *$fail*; >> >> <*MSG_Exprs* (*e*.Fe1) *e*.Fe2> <*MSG_Terms* *t*.Ft1 *t*.Ft2>; >> >> }; >> >> ((*CONST* *t*.name) *e*.Fe1) *e*.Fe2, { >> >> *e*.Fe2 : (*CONST* *t*.name) *e*.Rest = (*CONST* *t*.name) <*MSG_Exprs* >> (*e*.Fe1) *e*.Rest>; >> >> <*MSG_Exprs* (<*Format_Exp* <*Lookup* &*Const* *t*.name>> *e*.Fe1) >> *e*.Fe2>; >> >> }; >> >> (*e*.Fe1 (*CONST* *t*.name)) *e*.Fe2, { >> >> *e*.Fe2 : *e*.Rest (*CONST* *t*.name) = <*MSG_Exprs* (*e*.Fe1) *e*.Rest> >> (*CONST* *t*.name); >> >> <*MSG_Exprs* (*e*.Fe1 <*Format_Exp* <*Lookup* &*Const* *t*.name>>) >> *e*.Fe2>; >> >> }; >> >> (*e*.Fe1) (*CONST* *t*.name) *e*.Fe2 = >> >> <*MSG_Exprs* (*e*.Fe1) <*Format_Exp* <*Lookup* &*Const* *t*.name>> >> *e*.Fe2>; >> >> (*e*.Fe1) *e*.Fe2 (*CONST* *t*.name) = >> >> <*MSG_Exprs* (*e*.Fe1) *e*.Fe2 <*Format_Exp* <*Lookup* &*Const* >> *t*.name>>>; >> >> (*e*.Fe1) *e*.Fe2, { >> >> <*IsEmpty_Expr* *e*.Fe1>, <*IsEmpty_Expr* *e*.Fe2> = */*empty*/*; >> >> */* * >> >> * * If both e.Fe1 and e.Fe2 have non-(EVAR) terms then we can unify* >> >> * * them to (VVAR). Be VERY careful! We can meet &C, but it easy can be* >> >> * * that it points to empty expression.* >> >> * */* >> >> \*?* >> >> *e*.Fe1 : *e* *t*.Ft1 *e*, *t*.Ft1 : \{ >> >> (*VVAR*); >> >> (*CONST* *t*.name), # <*IsEmpty_Const* *t*.name>; >> >> } \*!* >> >> *e*.Fe2 : *e* *t*.Ft2 *e*, *t*.Ft2 : \{ >> >> (*VVAR*); >> >> (*CONST* *t*.name), # <*IsEmpty_Const* *t*.name>; >> >> } = >> >> (*VVAR*); >> >> */** >> >> * * Else at least one of expressions has form of (EVAR)...(EVAR). So we* >> >> * * should return (EVAR).* >> >> * */* >> >> (*EVAR*); >> >> }; >> >> }; >> >> >> >> *MSG_Terms* { >> >> (*PAREN* *e*.Fe1) (*PAREN* *e*.Fe2) = (*PAREN* <*MSG_Exprs* (*e*.Fe1) >> *e*.Fe2>); >> >> *t*.Ft *t*.Ft = *t*.Ft; >> >> *s* *s* = (*SVAR*); >> >> (*SVAR*) *s* = (*SVAR*); >> >> *s* (*SVAR*) = (*SVAR*); >> >> (*SVAR*) (*SVAR*) = (*SVAR*); >> >> (*REF* *e*) *s* = (*SVAR*); >> >> *s* (*REF* *e*) = (*SVAR*); >> >> (*REF* *e*) (*SVAR*) = (*SVAR*); >> >> (*SVAR*) (*REF* *e*) = (*SVAR*); >> >> *t* *t* = (*TVAR*); >> >> }; >> >> >> >> Хотел бы просто дать ссылку на исходники, но, к сожалению, сайт с ними >> лежит (что с ним довольно регулярно случается, так как никто не замечает, >> когда он падает). >> >> >> >> Антон >> >> >> >> >> >