procmail
[Top] [All Lists]

Re: Any logical combination of conditions

2001-04-09 09:54:26
Marie asked,

| What I want to do is to combine conditions.
| Examples:
|
| (cond1 AND cond2 AND cond3) OR (cond4 AND cond5) OR cond6
|
| Is there a general algorithm or a general way of composing those
| combinations?

The only *general* way I can think of is rather inefficient, because it
requires testing all six conditions for every piece of incoming mail.
However, it can be extrapolated to any tangle of ORing and ANDing:

 :0 condition-related_flags
 * 1^0 cond1
 * 1^0 cond2
 * 1^0 cond3
 * 10^0 cond4
 * 10^0 cond5
 * 100^0 cond6
 {
  SCORE = $=

  :0 action-related_flags local_lock_if_needed
  * SCORE ?? 1..|2.$|3$
  action
 }

If you had wanted to test for cond6 AND (cond4 OR cond5) AND (cond1 OR
cond2 or cond3) the regexp would have been

   1[12][123]

instead.  Well, actually with ANDs instead of ORs at the outermost level,
this would be much easier:

 :0 flags # for my example, not for Marie's
 * cond6
 * cond4|cond5
 * cond1|cond2|cond3
 action

Back to the original example, you can handle it this way if you aren't
insistent on having the action show up only once in the code:

 :0 flags
 * cond6
 action
 :0E
 * cond4
 * cond5
 action
 :0E
 * cond1
 * cond2
 * cond3
 action

I was trying to think of a way to make one recipe of all of them using
scoring that deliberately hit the supremum or the infemum at points after the
model of something Philip showed me once, but it is messy and difficult, and
it provides no guidelines for the general case.

Since all conditions on this recipe are weighted, a supremum score at any
point will skip the remaining conditions (because none are unweighted) and
run the action; an infemum score at any point will bail on the recipe (as it
would even if there were unweighted conditions).  Here we go.

 :0 flags
 * 2147483647^0 cond6
# If cond6 matched, the score hit supremum and procmail skipped to the
# action, so if we're still here, the score is 0.
 * 1073741824^0 cond4
 * 1073741824^0 cond5
# If cond4 and cond5 both matched, the score hit supremum and procmail skipped
# to the action, so if we're still here, the score is either 0 (if neither 
# cond4 nor cond5 matched) or +1073741824 (if cond4 or cond5 matched but not
# both), and henceforth we have to allow for both possibilities.
 * -1073741824^0
# Now the score is either -1073741824 or 0.
 * -2147483647^0 ! cond1
 * -2147483647^0 ! cond2
 * -2147483647^0 ! cond3
# If any of cond1, cond2, or cond3 failed, the score hit infemum and procmail
# bailed on the recipe.  If we are here, we know that cond1, cond2, and cond3
# all matched and we want the recipe to be deemed a match, but the score is
# still either -1073741824 or 0, so we need to make it positive:
 * 1073741825^0
# Now the score is either +1 or +1073741825, so procmail will run the action.
 action

_______________________________________________
procmail mailing list
procmail(_at_)lists(_dot_)RWTH-Aachen(_dot_)DE
http://MailMan.RWTH-Aachen.DE/mailman/listinfo/procmail