123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293(****************************************************************************)(* *)(* This file is part of MOPSA, a Modular Open Platform for Static Analysis. *)(* *)(* Copyright (C) 2017-2019 The MOPSA Project. *)(* *)(* This program is free software: you can redistribute it and/or modify *)(* it under the terms of the GNU Lesser General Public License as published *)(* by the Free Software Foundation, either version 3 of the License, or *)(* (at your option) any later version. *)(* *)(* This program is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* You should have received a copy of the GNU Lesser General Public License *)(* along with this program. If not, see <http://www.gnu.org/licenses/>. *)(* *)(****************************************************************************)(** Lattice of pairs *)openCore.All(** Signature of ordered types with printers *)moduletypeORDER=sigtypetvalcompare:t->t->intvalprint:Print.printer->t->unitendmoduleMake(First:LATTICE)(Second:LATTICE)=structtypet=First.t*Second.tletbottom:t=First.bottom,Second.bottomlettop:t=First.top,Second.topletsingleton(x:t):t=xletmap_fst(f:(First.t->First.t))((a,b)asx:t):t=leta'=fainifa'==athenxelse(a',b)letmap_snd(f:(Second.t->Second.t))((a,b)asx:t):t=letb'=fbinifb==b'thenxelse(a,b')letis_bottom((a,b):t):bool=First.is_bottoma||Second.is_bottombletsubset((a1,b1):t)((a2,b2):t):bool=First.subseta1a2&&Second.subsetb1b2letapplyf1f2((v1,v2)asv)=letr1=f1v1inletr2=f2v2inifr1==v1&&r2==v2thenvelse(r1,r2)letapply2f1f2((v1,v2)asv)((w1,w2)asw)=letr1=f1v1w1inletr2=f2v2w2inifr1==v1&&r2==v2thenvelseifr1==w1&&r2==w2thenwelse(r1,r2)letjoin((v1,v2)asv:t)((w1,w2)asw:t):t=ifv1==w1&&v2==w2thenvelseapply2First.joinSecond.joinvwletmeet((v1,v2)asv:t)((w1,w2)asw:t):t=ifv1==w1&&v2==w2thenvelseapply2First.meetSecond.meetvwletwidenctx((v1,v2)asv:t)((w1,w2)asw:t):t=ifv1==w1&&v2==w2thenvelseapply2(First.widenctx)(Second.widenctx)vwletprintprinter((a,b):t):unit=pp_obj_list~lopen:"("~lsep:","~lclose:")"printer[pboxFirst.printa;pboxSecond.printb]end