Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$-variable pattern matching and nested denominators #400

Closed
tueda opened this issue Nov 15, 2021 · 3 comments
Closed

$-variable pattern matching and nested denominators #400

tueda opened this issue Nov 15, 2021 · 3 comments

Comments

@tueda
Copy link
Collaborator

tueda commented Nov 15, 2021

In the following program, in the 1st module, I use the denominators statement and then try a pattern matching (the id statement) with an expression captured in a $-variable, but it fails. After .sort, in the 2nd module, the same code somehow works.

#-
Off stats;
S x;
CF den;
L F = 1/(1+1/(1+x));
P +s;
.sort;
denominators den;
* Just after the denominators statement, the following doesn't work.
if (match(den(x?$x1)));
  P "matched: %$ in %t", $x1;
  id den($x1) = 1;
endif;
P +s;
.sort;
* After sorting, it works.
if (match(den(x?$x2)));
  P "matched: %$ in %t", $x2;
  id den($x2) = 1;
endif;
P +s;
.end;
FORM 4.2.1 (Nov 10 2020, v4.2.1-30-gb0e72a8) 64-bits  Run: Mon Nov 15 12:37:30 2021
    #-

   F =
       + 1/(1 + 1/(1 + x))
      ;

matched: 1 + den(1 + x) in  + den(1 + den(1 + x))

   F =
       + den(1 + den(1 + x))
      ;

matched: 1 + den(1 + x) in  + den(1 + den(1 + x))

   F =
       + 1
      ;

  0.00 sec out of 0.00 sec

If this works in the 2nd module, then it should also work in the 1st module.

@benruijl
Copy link
Collaborator

Before the sort, F looks like:

34  150  30  1  27  1  4  1  1  3  21  150  17  1  14  0  4  1  1  3  8  1  4  20
  1  1  1  3  1  1  3  1  1  3

and after like

34  150  30  0  27  0  4  1  1  3  21  150  17  0  14  0  4  1  1  3  8  1  4  20
1  1  1  3  1  1  3  1  1  3

The only difference is the dirty flag, which then seems to prevent the match.

Forcing a term normalization after denominators by adding a Multiply 1; removes the dirty flag and restores the pattern match.

So it seems a necessary normalization call is missing at the end of the denominators routine.

@benruijl
Copy link
Collaborator

benruijl commented Oct 11, 2022

Changing the code in proces.c to add normalization:

case TYPEDENOMINATORS:
    if ( DenToFunction(term,C->lhs[level][2]) ) Normalize(BHEAD term);
    break;

Only normalizes the first level for some reason:

34  150  30  0  27  1  4  1  1  3  21  150  17  1  14  0  4  1  1  3  8  1  4  20
  1  1  1  3  1  1  3  1  1  3

@tueda
Copy link
Collaborator Author

tueda commented Oct 11, 2022

OK, so actually $-variables are not needed to reproduce this bug and a reduced test code is

S x;
CF den;
L F = 1/(1+1/(1+x));
.sort
denominators den;
P "%r";
multiply 1;
P "%r";
.end

where the two lines of P "%r" should print the same result, if the term is correctly normalized after denominators.

If you call Normalize() then maybe you need to check the return value for some errors (I'm totally not sure, though).

The following

if ( DenToFunction(term,C->lhs[level][2]) ) goto ReStart;

seems to work, but may be overkill?

@tueda tueda mentioned this issue Nov 2, 2022
tueda added a commit that referenced this issue Nov 7, 2022
- Format allfloat (see also #216)
- Format without line length
- moebius_
- #400
- all example.frm <-> reference manual correspondence
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants